Browse Source

CLDC-3505: Fix tests for hard year end part 4 (#2509)

* Add in past end dates for testing

* Temporarily disable test marked to delete at year end

* Remove one off reinfer_local_authority task

* Update validator_spec

* Set 2024 date in form_handler_spec to be during crossover period as needed

* Use bulk_upload.year_combo for comparison in request tests to avoid year dependancy

* Update BU log creator specs for 2024

* Use year combo function in bulk upload mailer tests

* Refactor lettings validator_spec

* More fixes

* More work on bu validator specs - mostly sales

* Remove pre 2023 test

* More use of bulk_upload.year_combo in request tests

* Fix lint

* Tweak bulk upload error row component tests for year changes

* Further fixes

* Fix 2023 lettings row parser spec

* Sales log to csv fix

* Refactor BU processor tests

* Fix field number row identifier

* Fix linting

* More years in request spec

* fix

* Don't use db unnecessarily in financial validations spec

* Fix sale date changing 2024 -> 2023 test

* Add tests for bulk_upload.year_combo

* Update bu factory year specification

* Refactoring

* Linting

* Don't use helper in factory

* Remove new 2023 specific test

* Remove dummy end dates
pull/2518/head
Rachael Booth 5 months ago committed by GitHub
parent
commit
636e40fc9d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 14
      lib/tasks/reinfer_local_authority.rake
  2. 39
      spec/components/bulk_upload_error_row_component_spec.rb
  3. 2
      spec/factories/bulk_upload.rb
  4. 3
      spec/factories/sales_log.rb
  5. 88
      spec/lib/tasks/reinfer_local_authority_spec.rb
  6. 4
      spec/mailers/bulk_upload_mailer_spec.rb
  7. 15
      spec/models/bulk_upload_spec.rb
  8. 4
      spec/models/form_handler_spec.rb
  9. 12
      spec/models/lettings_log_spec.rb
  10. 31
      spec/models/sales_log_spec.rb
  11. 24
      spec/models/validations/sales/financial_validations_spec.rb
  12. 4
      spec/requests/bulk_upload_lettings_results_controller_spec.rb
  13. 6
      spec/requests/bulk_upload_lettings_resume_controller_spec.rb
  14. 2
      spec/requests/bulk_upload_lettings_soft_validations_check_controller_spec.rb
  15. 2
      spec/requests/bulk_upload_sales_results_controller_spec.rb
  16. 6
      spec/requests/bulk_upload_sales_resume_controller_spec.rb
  17. 2
      spec/requests/bulk_upload_sales_soft_validations_check_controller_spec.rb
  18. 6
      spec/requests/form_controller_spec.rb
  19. 36
      spec/services/bulk_upload/lettings/log_creator_spec.rb
  20. 383
      spec/services/bulk_upload/lettings/validator_spec.rb
  21. 37
      spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb
  22. 293
      spec/services/bulk_upload/processor_spec.rb
  23. 34
      spec/services/bulk_upload/sales/log_creator_spec.rb
  24. 360
      spec/services/bulk_upload/sales/validator_spec.rb
  25. 2
      spec/services/csv/sales_log_csv_service_spec.rb
  26. 94
      spec/support/bulk_upload/lettings_log_to_csv.rb
  27. 92
      spec/support/bulk_upload/sales_log_to_csv.rb

14
lib/tasks/reinfer_local_authority.rake

@ -1,14 +0,0 @@
desc "Reinfers LA from postcode where it's missing"
task reinfer_local_authority: :environment do
LettingsLog.filter_by_year(2023).where(needstype: 1, la: nil).where.not(postcode_full: nil).find_each do |log|
log.process_postcode_changes!
Rails.logger.info "Invalid lettings log: #{log.id}" unless log.save
end
SalesLog.filter_by_year(2023).where(la: nil).where.not(postcode_full: nil).find_each do |log|
log.process_postcode_changes!
Rails.logger.info "Invalid sales log: #{log.id}" unless log.save
end
end

39
spec/components/bulk_upload_error_row_component_spec.rb

@ -6,7 +6,7 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
let(:tenant_code) { SecureRandom.hex(4) }
let(:property_ref) { SecureRandom.hex(4) }
let(:purchaser_code) { nil }
let(:field) { :field_134 }
let(:field) { :field_130 }
let(:error) { "some error" }
let(:bulk_upload) { create(:bulk_upload, :lettings) }
let(:bulk_upload_errors) do
@ -45,10 +45,28 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
expect(result).to have_content(expected)
end
it "renders the question for lettings" do
expected = "What do you expect the outstanding amount to be?"
result = render_inline(described_class.new(bulk_upload_errors:))
expect(result).to have_content(expected)
context "when the bulk upload is for 2024" do
context "with a lettings bulk upload" do
let(:bulk_upload) { build(:bulk_upload, :lettings, year: 2024) }
let(:field) { :field_130 }
it "renders the expected question" do
expected = "What do you expect the outstanding amount to be?"
result = render_inline(described_class.new(bulk_upload_errors:))
expect(result).to have_content(expected)
end
end
context "with a sales bulk upload" do
let(:bulk_upload) { create(:bulk_upload, :sales, year: 2024) }
let(:field) { :field_86 }
it "renders the expected question" do
expected = "Is this a staircasing transaction?"
result = render_inline(described_class.new(bulk_upload_errors:))
expect(result).to have_content(expected)
end
end
end
context "when tenant_code not present" do
@ -78,17 +96,6 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
end
end
context "when a sales bulk upload" do
let(:bulk_upload) { create(:bulk_upload, :sales) }
let(:field) { :field_87 }
it "renders the question for sales" do
expected = "Is this a staircasing transaction?"
result = render_inline(described_class.new(bulk_upload_errors:))
expect(result).to have_content(expected)
end
end
it "renders the error" do
expected = error
result = render_inline(described_class.new(bulk_upload_errors:))

2
spec/factories/bulk_upload.rb

@ -4,7 +4,7 @@ FactoryBot.define do
factory :bulk_upload do
user
log_type { BulkUpload.log_types.values.sample }
year { 2023 }
year { Time.zone.now.month >= 4 ? Time.zone.now.year : Time.zone.now.year - 1 }
identifier { SecureRandom.uuid }
sequence(:filename) { |n| "bulk-upload-#{n}.csv" }
needstype { 1 }

3
spec/factories/sales_log.rb

@ -128,8 +128,7 @@ FactoryBot.define do
pregla { 1 }
pregother { 1 }
pregghb { 1 }
hhregres { 1 }
hhregresstill { 4 }
hhregres { 7 }
ppcodenk { 1 }
prevten { 1 }
previous_la_known { 0 }

88
spec/lib/tasks/reinfer_local_authority_spec.rb

@ -1,88 +0,0 @@
require "rails_helper"
require "rake"
RSpec.describe "reinfer_local_authority" do
describe ":reinfer_local_authority", type: :task do
subject(:task) { Rake::Task["reinfer_local_authority"] }
before do
Rake.application.rake_require("tasks/reinfer_local_authority")
Rake::Task.define_task(:environment)
task.reenable
end
context "when the rake task is run" do
context "and there is a general needs type lettings log with postcode and without LA" do
let(:log) { create(:lettings_log, :completed, postcode_full: "AA1 1AA", status: "completed", startdate: Time.zone.local(2023, 4, 1)) }
it "updates the la if it can be inferred" do
log.la = nil
log.save!(validate: false)
task.invoke
log.reload
expect(log.la).to eq("E09000033")
expect(log.status).to eq("completed")
end
it "does not update the la if it cannot be inferred and sets status to in_progress" do
log.la = nil
log.postcode_full = "B11AB"
log.save!(validate: false)
task.invoke
log.reload
expect(log.la).to be_nil
expect(log.status).to eq("in_progress")
end
end
context "and the lettings log has a validation error" do
let(:log) { build(:lettings_log, :completed, postcode_full: "some fake postcode", la: nil, status: "completed", startdate: Time.zone.local(2023, 4, 1)) }
it "logs invalid log ID" do
log.save!(validate: false)
expect(Rails.logger).to receive(:info).with("Invalid lettings log: #{log.id}")
task.invoke
end
end
context "and there is a sales log with postcode and without LA" do
let(:log) { create(:sales_log, :completed, postcode_full: "AA1 1AA", status: "completed", saledate: Time.zone.local(2023, 4, 1)) }
it "updates the la if it can be inferred" do
log.la = nil
log.save!(validate: false)
task.invoke
log.reload
expect(log.la).to eq("E09000033")
expect(log.status).to eq("completed")
end
it "does not update the la if it cannot be inferred and sets status to in_progress" do
log.la = nil
log.postcode_full = "B11AB"
log.save!(validate: false)
task.invoke
log.reload
expect(log.la).to be_nil
expect(log.status).to eq("in_progress")
end
end
context "and the sales log has a validation error" do
let(:log) { build(:sales_log, :completed, postcode_full: "some fake postcode", la: nil, status: "completed", saledate: Time.zone.local(2023, 4, 1)) }
it "logs invalid log ID" do
log.save!(validate: false)
expect(Rails.logger).to receive(:info).with("Invalid sales log: #{log.id}")
task.invoke
end
end
end
end
end

4
spec/mailers/bulk_upload_mailer_spec.rb

@ -46,7 +46,7 @@ RSpec.describe BulkUploadMailer do
filename: bulk_upload.filename,
log_type: "lettings",
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
success_description: "The lettings 2023/24 data you uploaded has been checked. The 0 logs you uploaded are now complete.",
success_description: "The lettings #{bulk_upload.year_combo} data you uploaded has been checked. The 0 logs you uploaded are now complete.",
logs_link: clear_filters_url(filter_type: "lettings_logs"),
},
)
@ -113,7 +113,7 @@ RSpec.describe BulkUploadMailer do
title: "Check your file data",
filename: bulk_upload.filename,
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
description: "Some of your 2023/24 lettings data might not be right. Click the link below to review the potential errors, and check your file to see if the data is correct.",
description: "Some of your #{bulk_upload.year_combo} lettings data might not be right. Click the link below to review the potential errors, and check your file to see if the data is correct.",
cta_link: bulk_upload_lettings_soft_validations_check_url(bulk_upload, page: "confirm-soft-errors"),
},
)

15
spec/models/bulk_upload_spec.rb

@ -36,4 +36,19 @@ RSpec.describe BulkUpload, type: :model do
end
end
end
describe "year_combo" do
[
{ year: 2023, expected_value: "2023/24" },
{ year: 2024, expected_value: "2024/25" },
].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]) }
it "returns the expected year combination string" do
expect(bulk_upload.year_combo).to eql(test_case[:expected_value])
end
end
end
end
end

4
spec/models/form_handler_spec.rb

@ -246,8 +246,8 @@ RSpec.describe FormHandler do
end
end
context "when only archived form form is defined in JSON (current collection start year 2024 onwards)" do # TODO: CLDC-3505 remove this test on year hard end
let(:now) { Time.utc(2024, 9, 20) }
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

12
spec/models/lettings_log_spec.rb

@ -512,18 +512,6 @@ RSpec.describe LettingsLog do
create_list(:location, 2, scheme: new_scheme)
end
context "with a 2023 log" do
let(:log) { create(:lettings_log, :completed, :sh, :ignore_validation_errors, startdate: Time.zone.local(2024, 1, 1), owning_organisation:, scheme_id: old_scheme.id, location_id: old_location.id) }
it "clears the location set on the log" do
expect { log.update!(scheme: new_scheme) }.to change(log, :location_id).from(old_location.id).to(nil)
end
it "recalculates the log status" do
expect { log.update!(scheme: new_scheme) }.to change(log, :status).from("completed").to("in_progress")
end
end
context "with a current year log" do
let(:log) { create(:lettings_log, :completed, :sh, :startdate_today, owning_organisation:, scheme_id: old_scheme.id, location_id: old_location.id) }

31
spec/models/sales_log_spec.rb

@ -564,37 +564,6 @@ RSpec.describe SalesLog, type: :model do
expect(record_from_db["la"]).to eq("E08000003")
end
context "with 23/24 logs" do
let(:address_sales_log_23_24) do
described_class.create({
owning_organisation:,
assigned_to: assigned_to_user,
ppcodenk: 1,
postcode_full: "CA10 1AA",
saledate: Time.zone.local(2023, 5, 2),
})
end
before do
WebMock.stub_request(:get, /api\.postcodes\.io\/postcodes\/CA101AA/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Eden","codes":{"admin_district":"E07000030"}}}', headers: {})
end
it "correctly infers new la" do
record_from_db = described_class.find(address_sales_log_23_24.id)
expect(address_sales_log_23_24.la).to eq("E06000064")
expect(record_from_db["la"]).to eq("E06000064")
end
it "does not set previous postcode or previous la for discounted sale" do
address_sales_log_23_24.update!(ownershipsch: 2, ppostcode_full: nil, prevloc: nil)
record_from_db = described_class.find(address_sales_log_23_24.id)
expect(address_sales_log_23_24.ppostcode_full).to eq(nil)
expect(record_from_db["ppostcode_full"]).to eq(nil)
expect(record_from_db["prevloc"]).to eq(nil)
end
end
context "with 24/25 logs" do
let(:address_sales_log_24_25) do
described_class.create({

24
spec/models/validations/sales/financial_validations_spec.rb

@ -10,8 +10,7 @@ RSpec.describe Validations::Sales::FinancialValidations do
context "when buying in a non london borough" do
before do
record.update!(la: "E08000035")
record.reload
record.la = "E08000035"
end
it "adds errors if buyer 1 has income over 80,000" do
@ -80,8 +79,7 @@ RSpec.describe Validations::Sales::FinancialValidations do
context "when buying in a london borough" do
before do
record.update!(la: "E09000030")
record.reload
record.la = "E09000030"
end
it "adds errors if buyer 1 has income over 90,000" do
@ -311,12 +309,10 @@ RSpec.describe Validations::Sales::FinancialValidations do
context "when buyer 2 is not a child" do
before do
record.update!(ecstat2: rand(0..8))
record.reload
record.ecstat2 = rand(0..8)
end
it "does not add an error if buyer 2 has an income" do
record.ecstat2 = rand(0..8)
record.income2 = 40_000
financial_validator.validate_child_income(record)
expect(record.errors).to be_empty
@ -324,30 +320,20 @@ RSpec.describe Validations::Sales::FinancialValidations do
end
context "when buyer 2 is a child" do
let(:record) { build(:sales_log, :saledate_today, ecstat2: 9) }
it "does not add an error if buyer 2 has no income" do
record.saledate = Time.zone.local(2023, 4, 3)
record.ecstat2 = 9
record.income2 = 0
financial_validator.validate_child_income(record)
expect(record.errors).to be_empty
end
it "adds errors if buyer 2 has an income" do
record.saledate = Time.zone.local(2023, 4, 3)
record.ecstat2 = 9
record.income2 = 40_000
financial_validator.validate_child_income(record)
expect(record.errors["ecstat2"]).to include(match I18n.t("validations.financial.income.child_has_income"))
expect(record.errors["income2"]).to include(match I18n.t("validations.financial.income.child_has_income"))
end
it "does not add an error if the saledate is before the 23/24 collection window" do
record.saledate = Time.zone.local(2022, 4, 3)
record.ecstat2 = 9
record.income2 = 40_000
financial_validator.validate_child_income(record)
expect(record.errors).to be_empty
end
end
end

4
spec/requests/bulk_upload_lettings_results_controller_spec.rb

@ -16,7 +16,7 @@ RSpec.describe BulkUploadLettingsResultsController, type: :request do
get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings (2023/24)")
expect(response.body).to include("Bulk upload for lettings (#{bulk_upload.year_combo})")
end
it "renders the bulk upload filename" do
@ -68,7 +68,7 @@ RSpec.describe BulkUploadLettingsResultsController, type: :request do
get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings (2023/24)")
expect(response.body).to include("Bulk upload for lettings (#{bulk_upload.year_combo})")
end
it "renders correct number of errors" do

6
spec/requests/bulk_upload_lettings_resume_controller_spec.rb

@ -41,7 +41,7 @@ RSpec.describe BulkUploadLettingsResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("View the error report")
expect(response.body).to include("How would you like to fix the errors?")
expect(response.body).to include(bulk_upload.filename)
@ -180,7 +180,7 @@ RSpec.describe BulkUploadLettingsResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs")
@ -222,7 +222,7 @@ RSpec.describe BulkUploadLettingsResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs")

2
spec/requests/bulk_upload_lettings_soft_validations_check_controller_spec.rb

@ -15,7 +15,7 @@ RSpec.describe BulkUploadLettingsSoftValidationsCheckController, type: :request
get "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("Check these 2 answers")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Are these fields correct?")

2
spec/requests/bulk_upload_sales_results_controller_spec.rb

@ -16,7 +16,7 @@ RSpec.describe BulkUploadSalesResultsController, type: :request do
get "/sales-logs/bulk-upload-results/#{bulk_upload.id}"
expect(response).to be_successful
expect(response.body).to include("Bulk Upload for sales (2023/24)")
expect(response.body).to include("Bulk Upload for sales (#{bulk_upload.year_combo})")
end
it "renders correct number of errors" do

6
spec/requests/bulk_upload_sales_resume_controller_spec.rb

@ -41,7 +41,7 @@ RSpec.describe BulkUploadSalesResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("View the error report")
expect(response.body).to include("How would you like to fix the errors?")
expect(response.body).to include(bulk_upload.filename)
@ -180,7 +180,7 @@ RSpec.describe BulkUploadSalesResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs")
@ -222,7 +222,7 @@ RSpec.describe BulkUploadSalesResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs")

2
spec/requests/bulk_upload_sales_soft_validations_check_controller_spec.rb

@ -15,7 +15,7 @@ RSpec.describe BulkUploadSalesSoftValidationsCheckController, type: :request do
get "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2023/24")
expect(response.body).to include(bulk_upload.year_combo)
expect(response.body).to include("Check these 2 answers")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Are these fields correct?")

6
spec/requests/form_controller_spec.rb

@ -1016,7 +1016,7 @@ RSpec.describe FormController, type: :request do
end
end
context "when the sale date changes from 2024 to 2023" do # TODO: CLDC-3505 remove this test on year hard end
context "when the sale date changes from 2024 to 2023" do
let(:sales_log) { create(:sales_log, owning_organisation: organisation, managing_organisation:, assigned_to: user) }
let(:params) do
{
@ -1034,10 +1034,10 @@ RSpec.describe FormController, type: :request do
before do
organisation.managing_agents << managing_organisation
organisation.reload
sales_log.saledate = Time.zone.local(2024, 12, 1)
sales_log.saledate = Time.zone.local(2024, 5, 1)
sales_log.save!(validate: false)
sales_log.reload
Timecop.freeze(Time.zone.local(2024, 12, 1))
Timecop.freeze(Time.zone.local(2024, 5, 1))
Singleton.__init__(FormHandler)
end

36
spec/services/bulk_upload/lettings/log_creator_spec.rb

@ -6,13 +6,13 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
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:) }
let(:csv_parser) { instance_double(BulkUpload::Lettings::Year2023::CsvParser) }
let(:row_parser) { instance_double(BulkUpload::Lettings::Year2023::RowParser) }
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(:log) { build(:lettings_log, :completed, assigned_to: user, owning_organisation: owning_org, managing_organisation: owning_org) }
before do
allow(BulkUpload::Lettings::Year2023::CsvParser).to receive(:new).and_return(csv_parser)
allow(BulkUpload::Lettings::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)
@ -20,23 +20,7 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
allow(row_parser).to receive(:blank_row?).and_return(false)
end
around do |example|
Timecop.freeze(Time.zone.local(2023, 4, 1)) do
Singleton.__init__(FormHandler)
example.run
end
end
describe "#call" do
before do
Timecop.freeze(Time.zone.local(2023, 11, 10))
Singleton.__init__(FormHandler)
end
after do
Timecop.return
end
context "when a valid csv with new log" do
it "creates a new log" do
expect { service.call }.to change(LettingsLog, :count)
@ -77,17 +61,11 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
build(
:lettings_log,
:completed,
renttype: 3,
age1_known: 0,
age1: 5,
owning_organisation: owning_org,
managing_organisation: owning_org,
assigned_to: user,
national: 18,
waityear: 9,
joint: 2,
tenancy: 9,
ppcodenk: 1,
)
end
@ -148,18 +126,12 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
build(
:lettings_log,
:completed,
renttype: 3,
age1: 22,
age1_known: 0,
ecstat1: 5,
owning_organisation: owning_org,
managing_organisation: owning_org,
assigned_to: user,
national: 18,
waityear: 9,
joint: 2,
tenancy: 9,
ppcodenk: 1,
)
end

383
spec/services/bulk_upload/lettings/validator_spec.rb

@ -3,186 +3,110 @@ require "rails_helper"
RSpec.describe BulkUpload::Lettings::Validator do
subject(:validator) { described_class.new(bulk_upload:, path:) }
let(:organisation) { create(:organisation, old_visible_id: "3") }
let(:organisation) { create(:organisation, old_visible_id: "3", rent_periods: [2]) }
let(:user) { create(:user, organisation:) }
let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2024, 3, 3)) }
let(:bulk_upload) { create(:bulk_upload, user:) }
let(:log) { build(:lettings_log, :completed, period: 2, assigned_to: user) }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) }
let(:bulk_upload) { create(:bulk_upload, user:, year: log.collection_start_year) }
let(:path) { file.path }
let(:file) { Tempfile.new }
describe "validations" do
context "when 2023" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) }
context "when file has no headers" do
context "and too many columns" do
before do
file.write(("a" * 143).chars.join(","))
file.write("\n")
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Too many columns, please ensure you have used the correct template"])
end
end
context "and is empty" do
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Template is blank - The template must be filled in for us to create the logs and check if data is correct."])
end
end
context "and doesn't have too many columns" do
before do
file.write(("a" * 142).chars.join(","))
file.write("\n")
file.rewind
end
it "is valid" do
expect(validator).to be_valid
end
context "when file has headers" do
context "and is empty" do
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Template is blank - The template must be filled in for us to create the logs and check if data is correct."])
end
end
context "when file has headers" do
context "and is empty" do
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Template is blank - The template must be filled in for us to create the logs and check if data is correct."])
end
end
context "and file has extra invalid headers" do
let(:seed) { rand }
let(:field_numbers) { log_to_csv.default_field_numbers + %w[invalid_field_number] }
let(:field_values) { log_to_csv.to_row + %w[value_for_invalid_field_number] }
context "and file has extra invalid headers" do
let(:seed) { rand }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2023_field_numbers + %w[invalid_field_number] }
let(:field_values) { log_to_csv.to_2023_row + %w[value_for_invalid_field_number] }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is valid" do
expect(validator).to be_valid
end
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
context "and file has too few valid headers" do
let(:seed) { rand }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2023_field_numbers }
let(:field_values) { log_to_csv.to_2023_row }
before do
field_numbers.delete_at(20)
field_values.delete_at(20)
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"])
end
it "is valid" do
expect(validator).to be_valid
end
end
context "and file has too many valid headers" do
let(:seed) { rand }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2023_field_numbers + %w[23] }
let(:field_values) { log_to_csv.to_2023_row + %w[value] }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
context "and file has too few valid headers" do
let(:seed) { rand }
let(:field_numbers) { log_to_csv.default_field_numbers }
let(:field_values) { log_to_csv.to_row }
before do
field_numbers.delete_at(20)
field_values.delete_at(20)
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"])
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"])
end
end
context "when uploading a 2022 logs for 2023 bulk upload" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) }
let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2022, 5, 6), tenancycode: "5") }
context "with no headers" do
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.close
end
context "and file has too many valid headers" do
let(:seed) { rand }
let(:field_numbers) { log_to_csv.default_field_numbers + %w[23] }
let(:field_values) { log_to_csv.to_row + %w[value] }
it "is not valid" do
expect(validator).not_to be_valid
end
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
context "with headers" do
let(:seed) { rand }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2023_field_numbers }
let(:field_values) { log_to_csv.to_2023_row }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"])
end
end
end
context "when uploading a 2023 logs for 2024 bulk upload" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2024) }
let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2023, 5, 6), tenancycode: "5234234234234") }
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 "with no headers" do
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2024_csv_row)
file.close
end
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 }
it "is not valid" do
expect(validator).not_to be_valid
end
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
context "with headers" do
let(:seed) { rand }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2024_field_numbers }
let(:field_values) { log_to_csv.to_2024_row }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect start dates, please ensure you have used the correct template"])
end
end
end
end
describe "#call" do
context "when a valid csv" do
let(:path) { file_fixture("2023_24_lettings_bulk_upload_invalid.csv") }
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) }
before do
values = log_to_csv.to_2024_row
values[7] = nil
file.write(log_to_csv.default_2024_field_numbers_row)
file.write(log_to_csv.to_custom_csv_row(seed: nil, field_values: values))
file.rewind
end
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
@ -191,36 +115,39 @@ RSpec.describe BulkUpload::Lettings::Validator do
it "create validation error with correct values" do
validator.call
error = BulkUploadError.find_by(row: "9", field: "field_7", category: "setup")
error = BulkUploadError.find_by(row: "2", field: "field_8", category: "setup")
expect(error.field).to eql("field_7")
expect(error.field).to eql("field_8")
expect(error.error).to eql("You must answer tenancy start date (day)")
expect(error.tenant_code).to eql("123")
expect(error.property_ref).to be_nil
expect(error.row).to eql("9")
expect(error.cell).to eql("H9")
expect(error.col).to eql("H")
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("I2")
expect(error.col).to eql("I")
end
end
context "with arbitrary ordered 23/24 csv" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) }
let(:log) { build(:lettings_log, :completed) }
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:seed) { 321 }
around do |example|
FormHandler.instance.use_real_forms!
example.run
context "with a valid csv" do
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
FormHandler.instance.use_fake_forms!
it "does not create validation errors" do
expect { validator.call }.not_to change(BulkUploadError, :count)
end
end
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) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").default_2023_field_numbers_row(seed:))
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row(seed:))
log.needstype = nil
values = log_to_csv.to_2024_row
file.write(log_to_csv.default_2024_field_numbers_row(seed:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values: values))
file.close
end
@ -231,59 +158,71 @@ RSpec.describe BulkUpload::Lettings::Validator do
it "create validation error with correct values" do
validator.call
error = BulkUploadError.find_by(field: "field_5")
error = BulkUploadError.find_by(field: "field_4")
expect(error.field).to eql("field_5")
expect(error.error).to eql("You must answer letting type")
expect(error.field).to eql("field_4")
expect(error.error).to eql("You must answer needs type")
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("DD2")
expect(error.col).to eql("DD")
expect(error.cell).to eql("CY2")
expect(error.col).to eql("CY")
end
end
context "when duplicate rows present" do
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) { build(:lettings_log, :completed) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").default_2023_field_numbers_row)
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row)
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
it "creates errors" do
expect { validator.call }.to change(BulkUploadError.where(category: :setup, error: "This is a duplicate of a log in your file"), :count).by(22)
expect { validator.call }.to change(BulkUploadError.where(category: :setup, error: "This is a duplicate of a log in your file"), :count)
end
end
context "with unix line endings" do
let(:fixture_path) { file_fixture("2023_24_lettings_bulk_upload.csv") }
let(:file) { Tempfile.new }
let(:path) { file.path }
[
{ line_ending: "\n", name: "unix" },
{ line_ending: "\r\n", name: "windows" },
].each do |test_case|
context "with #{test_case[:name]} line endings" do
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:, line_ending: test_case[:line_ending]) }
before do
string = File.read(fixture_path)
string.gsub!("\r\n", "\n")
file.write(string)
file.rewind
end
context "with a valid file" do
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
it "does not create validation errors" do
expect { validator.call }.not_to change(BulkUploadError, :count)
end
end
context "with an invalid file" do
let(:log) { build(:lettings_log, :completed, assigned_to: user, owning_organisation: organisation, managing_organisation: organisation, declaration: nil) }
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
end
end
end
end
context "without headers" do
let(:log) { build(:lettings_log, :completed) }
let(:file) { Tempfile.new }
let(:path) { file.path }
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) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
@ -294,47 +233,29 @@ RSpec.describe BulkUpload::Lettings::Validator do
end
describe "#create_logs?" do
context "when all logs are valid" do
let(:target_path) { file_fixture("2023_24_lettings_bulk_upload.csv") }
it "returns truthy" do
validator.call
expect(validator).to be_create_logs
end
end
context "when there is an invalid log" do
let(:path) { file_fixture("2023_24_lettings_bulk_upload_invalid.csv") }
it "returns falsey" do
validator.call
expect(validator).not_to be_create_logs
end
end
context "when a log is not valid?" do
let(:log_1) { build(:lettings_log, :completed, assigned_to: user) }
let(:log_2) { build(:lettings_log, :completed, assigned_to: user) }
context "when a log has a clearable, non-setup error" do
let(:log_1) { build(:lettings_log, :completed, period: 2, assigned_to: user) }
let(:log_2) { build(:lettings_log, :completed, period: 2, assigned_to: user, age1: 5) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides: { illness: 100 }).to_2023_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log: log_1, col_offset: 0).to_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log: log_2, col_offset: 0).to_csv_row)
file.close
end
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
expect(validator).to be_create_logs
end
end
context "when all logs valid?" do
let(:log_1) { build(:lettings_log, :completed, renttype: 1, assigned_to: user) }
let(:log_2) { build(:lettings_log, :completed, renttype: 1, assigned_to: user) }
let(:log_1) { build(:lettings_log, :completed, period: 2, assigned_to: user) }
let(:log_2) { build(:lettings_log, :completed, period: 2, assigned_to: user) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log: log_1, col_offset: 0).to_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log: log_2, col_offset: 0).to_csv_row)
file.close
end
@ -344,13 +265,13 @@ RSpec.describe BulkUpload::Lettings::Validator do
end
end
context "when a single log wants to block log creation" do
context "when a log wants to block log creation" do
let(:unaffiliated_org) { create(:organisation) }
let(:log_1) { build(:lettings_log, :completed, renttype: 1, assigned_to: user, owning_organisation: unaffiliated_org) }
let(:log) { build(:lettings_log, :completed, assigned_to: user, owning_organisation: unaffiliated_org) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
@ -361,10 +282,10 @@ RSpec.describe BulkUpload::Lettings::Validator do
end
context "when a log has incomplete setup section" do
let(:log) { build(:lettings_log, :in_progress, assigned_to: user, startdate: Time.zone.local(2022, 5, 1)) }
let(:log) { build(:lettings_log, :completed, declaration: nil, assigned_to: user) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end

37
spec/services/bulk_upload/lettings/year2023/row_parser_spec.rb

@ -3,7 +3,7 @@ require "rails_helper"
RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
subject(:parser) { described_class.new(attributes) }
let(:now) { Time.zone.now.beginning_of_day }
let(:now) { Time.zone.local(2023, 12, 1) }
let(:attributes) { { bulk_upload: } }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: nil, year: 2023) }
@ -30,7 +30,8 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
before do
allow(FormHandler.instance).to receive(:lettings_in_crossover_period?).and_return(true)
Timecop.freeze(now)
create(:organisation_relationship, parent_organisation: owning_org, child_organisation: managing_org)
LaRentRange.create!(
@ -46,11 +47,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
)
end
around do |example|
Timecop.freeze(Date.new(2023, 10, 1)) do
FormHandler.instance.use_real_forms!
example.run
end
after do
Timecop.return
end
@ -369,7 +366,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when a supported housing log with chcharges already exists in the db" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2, year: 2023) }
let(:attributes) do
valid_attributes.merge({ field_15: scheme.old_visible_id,
field_4: "2",
@ -418,7 +415,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when a supported housing log different chcharges already exists in the db" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2, year: 2023) }
let(:attributes) do
valid_attributes.merge({ field_15: scheme.old_visible_id,
field_4: "2",
@ -513,7 +510,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when a supported housing log with chcharges already exists in the db" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2, year: 2023) }
let(:attributes) do
valid_attributes.merge({ field_16: "S#{scheme.id}",
field_4: "2",
@ -562,7 +559,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when a supported housing log different chcharges already exists in the db" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2, year: 2023) }
let(:attributes) do
valid_attributes.merge({ field_16: "S#{scheme.id}",
field_4: "2",
@ -901,7 +898,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when bulk upload is for supported housing" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2023) }
context "when general needs option selected" do
let(:attributes) { { bulk_upload:, field_5: "1", field_4: "2" } }
@ -1374,7 +1371,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when 4 ie referred by LA and is not general needs" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2023) }
let(:attributes) { { bulk_upload:, field_119: "4", field_4: "2" } }
it "is permitted" do
@ -1411,9 +1408,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when inside of collection year" do
let(:attributes) { { bulk_upload:, field_7: "1", field_8: "10", field_9: "22" } }
let(:attributes) { { bulk_upload:, field_7: "1", field_8: "10", field_9: "23" } }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2022) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2023) }
it "does not return errors" do
expect(parser.errors[:field_7]).not_to be_present
@ -1423,15 +1420,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when outside of collection year" do
around do |example|
Timecop.freeze(Date.new(2022, 4, 2)) do
example.run
end
end
let(:attributes) { { bulk_upload:, field_7: "1", field_8: "1", field_9: "22" } }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2022) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2023) }
it "returns setup errors" do
expect(parser.errors.where(:field_7, category: :setup)).to be_present
@ -1640,7 +1631,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end
context "when neither UPRN nor address fields are given for a supported housing record" do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: 2, year: 2023) }
let(:attributes) do
{ bulk_upload:,
field_15: scheme.old_visible_id,

293
spec/services/bulk_upload/processor_spec.rb

@ -6,6 +6,7 @@ RSpec.describe BulkUpload::Processor do
let(:bulk_upload) { create(:bulk_upload, :lettings, user:) }
let(:user) { create(:user, organisation: owning_org) }
let(:owning_org) { create(:organisation, old_visible_id: 123, rent_periods: [2]) }
let(:mock_validator) do
instance_double(
BulkUpload::Lettings::Validator,
@ -13,20 +14,35 @@ RSpec.describe BulkUpload::Processor do
call: nil,
total_logs_count: 1,
any_setup_errors?: false,
create_logs?: false,
create_logs?: true,
soft_validation_errors_only?: false,
)
end
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path:,
delete_local_file!: nil,
)
end
describe "#call" do
before do
Timecop.freeze(Time.zone.local(2023, 11, 10))
Singleton.__init__(FormHandler)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
after do
Timecop.return
end
let(:log) { build(:lettings_log, :completed, assigned_to: user) }
before do
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
log_to_csv = BulkUpload::LettingsLogToCsv.new(log:)
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
end
describe "#call" do
context "when errors exist from prior job run" do
let!(:existing_error) { create(:bulk_upload_error, bulk_upload:) }
@ -38,15 +54,6 @@ RSpec.describe BulkUpload::Processor do
end
context "when the bulk upload itself is not considered valid" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path: file_fixture("2023_24_lettings_bulk_upload.csv"),
delete_local_file!: nil,
)
end
let(:mock_validator) do
instance_double(
BulkUpload::Lettings::Validator,
@ -57,11 +64,6 @@ RSpec.describe BulkUpload::Processor do
)
end
before do
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
end
it "sends failure email" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
@ -88,27 +90,7 @@ RSpec.describe BulkUpload::Processor do
end
context "when the bulk upload processing throws an error" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path: file_fixture("2023_24_lettings_bulk_upload.csv"),
delete_local_file!: nil,
)
end
let(:mock_validator) do
instance_double(
BulkUpload::Lettings::Validator,
invalid?: false,
total_logs_count: 1,
)
end
before do
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
allow(mock_validator).to receive(:call).and_raise(StandardError)
end
@ -132,16 +114,7 @@ RSpec.describe BulkUpload::Processor do
end
end
context "when a log has an incomplete setup section" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path: file_fixture("2023_24_lettings_bulk_upload.csv"),
delete_local_file!: nil,
)
end
context "when a log has a setup error" do
let(:mock_validator) do
instance_double(
BulkUpload::Lettings::Validator,
@ -152,11 +125,6 @@ RSpec.describe BulkUpload::Processor do
)
end
before do
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
end
it "sends setup failure email" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
@ -170,37 +138,6 @@ RSpec.describe BulkUpload::Processor do
end
context "when processing a bulk with perfect data" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path:,
delete_local_file!: nil,
)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) do
build(
:lettings_log,
:completed,
owning_organisation: owning_org,
managing_organisation: owning_org,
assigned_to: user,
renttype: 1,
leftreg: 3,
)
end
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, col_offset: 0).to_2023_csv_row)
file.rewind
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
end
it "creates logs as not pending" do
expect { processor.call }.to change(LettingsLog.completed, :count).by(1)
end
@ -217,98 +154,10 @@ RSpec.describe BulkUpload::Processor do
end
end
context "when processing an empty file" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path:,
delete_local_file!: nil,
)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
end
it "sends failure email" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
allow(BulkUploadMailer).to receive(:send_bulk_upload_failed_service_error_mail).and_return(mail_double)
processor.call
expect(BulkUploadMailer).to have_received(:send_bulk_upload_failed_service_error_mail).with(
bulk_upload:,
errors: ["Template is blank - The template must be filled in for us to create the logs and check if data is correct."],
)
expect(mail_double).to have_received(:deliver_later)
end
end
context "when 2023-24" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path: file_fixture("2023_24_lettings_bulk_upload_empty_with_headers.csv"),
delete_local_file!: nil,
)
end
before do
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
end
it "sends failure email" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
allow(BulkUploadMailer).to receive(:send_bulk_upload_failed_service_error_mail).and_return(mail_double)
processor.call
expect(BulkUploadMailer).to have_received(:send_bulk_upload_failed_service_error_mail).with(
bulk_upload:,
errors: ["Template is blank - The template must be filled in for us to create the logs and check if data is correct."],
)
expect(mail_double).to have_received(:deliver_later)
end
end
context "when a bulk upload has an in progress log" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path:,
delete_local_file!: nil,
)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) do
LettingsLog.new(
lettype: 2,
renttype: 3,
owning_organisation: owning_org,
managing_organisation: owning_org,
startdate: Time.zone.local(2023, 10, 1),
renewal: 2,
declaration: 1,
)
end
let(:log) { build(:lettings_log, :setup_completed, assigned_to: user) }
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, col_offset: 0).to_2023_csv_row)
file.rewind
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
allow(mock_validator).to receive(:create_logs?).and_return(true)
allow(mock_validator).to receive(:soft_validation_errors_only?).and_return(false)
allow(FeatureToggle).to receive(:bulk_upload_duplicate_log_check_enabled?).and_return(true)
@ -341,58 +190,12 @@ RSpec.describe BulkUpload::Processor do
end
context "when a bulk upload has logs with only soft validations triggered" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path:,
delete_local_file!: nil,
)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) do
build(
:lettings_log,
:completed,
renttype: 3,
age1: 20,
ecstat1: 5,
owning_organisation: owning_org,
managing_organisation: owning_org,
assigned_to: nil,
national: 18,
waityear: 9,
joint: 2,
tenancy: 2,
ppcodenk: 1,
voiddate: Date.new(2022, 1, 1),
reason: 40,
leftreg: 3,
mrcdate: nil,
startdate: Date.new(2023, 10, 1),
tenancylength: nil,
)
end
before do
FormHandler.instance.use_real_forms!
file.write(BulkUpload::LettingsLogToCsv.new(log:, col_offset: 0).to_2023_csv_row)
file.rewind
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
allow(mock_validator).to receive(:create_logs?).and_return(true)
allow(mock_validator).to receive(:soft_validation_errors_only?).and_return(true)
allow(FeatureToggle).to receive(:bulk_upload_duplicate_log_check_enabled?).and_return(true)
end
after do
FormHandler.instance.use_fake_forms!
end
it "creates pending log" do
expect { processor.call }.to change(LettingsLog.pending, :count).by(1)
end
@ -421,42 +224,18 @@ RSpec.describe BulkUpload::Processor do
end
end
context "when upload has no setup errors something blocks log creation" do
let(:mock_downloader) do
context "when upload has something blocking log creation" do
let(:mock_validator) do
instance_double(
BulkUpload::Downloader,
BulkUpload::Lettings::Validator,
invalid?: false,
call: nil,
path:,
delete_local_file!: nil,
)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:other_user) { create(:user) }
let(:log) do
LettingsLog.new(
lettype: 2,
renttype: 3,
owning_organisation: owning_org,
managing_organisation: owning_org,
startdate: Time.zone.local(2023, 10, 1),
renewal: 2,
assigned_to: other_user, # unaffiliated user
declaration: 1,
total_logs_count: 1,
any_setup_errors?: false,
create_logs?: false,
)
end
before do
allow(BulkUpload::Lettings::Validator).to receive(:new).and_return(mock_validator)
file.write(BulkUpload::LettingsLogToCsv.new(log:, col_offset: 0).to_2023_csv_row)
file.rewind
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
end
it "sends correct_and_upload_again_mail" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
@ -471,12 +250,12 @@ RSpec.describe BulkUpload::Processor do
end
describe "#approve" do
let!(:log) { create(:lettings_log, bulk_upload:, status: "pending", skip_update_status: true, status_cache: "not_started") }
let!(:log) { create(:lettings_log, :in_progress, bulk_upload:, status: "pending", skip_update_status: true, status_cache: "in_progress") }
it "makes pending logs no longer pending" do
expect(log.status).to eql("pending")
processor.approve
expect(log.reload.status).to eql("not_started")
expect(log.reload.status).to eql("in_progress")
end
end
end

34
spec/services/bulk_upload/sales/log_creator_spec.rb

@ -6,13 +6,13 @@ RSpec.describe BulkUpload::Sales::LogCreator do
let(:owning_org) { create(:organisation, old_visible_id: 123) }
let(:user) { create(:user, organisation: owning_org) }
let(:bulk_upload) { create(:bulk_upload, :sales, user:) }
let(:csv_parser) { instance_double(BulkUpload::Sales::Year2023::CsvParser) }
let(:row_parser) { instance_double(BulkUpload::Sales::Year2023::RowParser) }
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) }
let(:log) { build(:sales_log, :completed, assigned_to: user, owning_organisation: owning_org, managing_organisation: owning_org) }
before do
allow(BulkUpload::Sales::Year2023::CsvParser).to receive(:new).and_return(csv_parser)
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)
@ -21,13 +21,6 @@ RSpec.describe BulkUpload::Sales::LogCreator do
end
describe "#call" do
around do |example|
Timecop.freeze(Time.zone.local(2023, 4, 22)) do
Singleton.__init__(FormHandler)
example.run
end
end
context "when a valid csv with new log" do
it "creates a new log" do
expect { service.call }.to change(SalesLog, :count)
@ -92,14 +85,15 @@ RSpec.describe BulkUpload::Sales::LogCreator do
build(
:sales_log,
:completed,
ownershipsch: 2,
pcodenk: 0,
ppcodenk: 0,
postcode_full: "AA11AA",
ppostcode_full: "BB22BB",
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
@ -111,10 +105,10 @@ RSpec.describe BulkUpload::Sales::LogCreator do
service.call
record = SalesLog.last
expect(record.pcodenk).to be_blank
expect(record.postcode_full).to be_blank
expect(record.ppcodenk).to be_blank
expect(record.ppostcode_full).to be_blank
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

360
spec/services/bulk_upload/sales/validator_spec.rb

@ -5,7 +5,9 @@ RSpec.describe BulkUpload::Sales::Validator do
let(:user) { create(:user, organisation:) }
let(:organisation) { create(:organisation, old_visible_id: "123") }
let(:bulk_upload) { create(:bulk_upload, user:) }
let(:log) { build(:sales_log, :completed, assigned_to: user) }
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:) }
let(:bulk_upload) { create(:bulk_upload, user:, year: log.collection_start_year) }
let(:path) { file.path }
let(:file) { Tempfile.new }
@ -40,185 +42,90 @@ RSpec.describe BulkUpload::Sales::Validator do
end
end
context "when trying to upload different year data for 2024 bulk upload" do
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) }
context "with a valid csv" do
let(:path) { file_fixture("2022_23_sales_bulk_upload.csv") }
it "is not valid" do
expect(validator).not_to be_valid
end
end
context "with unix line endings" do
let(:fixture_path) { file_fixture("2022_23_sales_bulk_upload.csv") }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
string = File.read(fixture_path)
string.gsub!("\r\n", "\n")
file.write(string)
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
end
end
context "without headers" do
let(:log) { build(:sales_log, :completed) }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
Timecop.freeze(Time.utc(2023, 10, 3))
file.write(BulkUpload::SalesLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2024_csv_row)
file.close
end
after do
Timecop.unfreeze
end
it "is not valid" do
expect(validator).not_to be_valid
end
before do
file.write(log_to_csv.default_2024_field_numbers_row)
file.write(log_to_csv.to_2024_csv_row)
file.rewind
end
context "with headers" do
let(:file) { Tempfile.new }
let(:seed) { rand }
let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2023, 10, 10)) }
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2024_field_numbers }
let(:field_values) { log_to_csv.to_2024_row }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect sale dates, please ensure you have used the correct template"])
end
end
context "when trying to upload 2024 year data for 2024 bulk upload" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2024) }
context "with headers" do
let(:file) { Tempfile.new }
let(:seed) { rand }
let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2024, 10, 10)) }
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2024_field_numbers }
let(:field_values) { log_to_csv.to_2024_row }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is valid" do
expect(validator).to be_valid
[
{ line_ending: "\n", name: "unix" },
{ line_ending: "\r\n", name: "windows" },
].each do |test_case|
context "with #{test_case[:name]} line endings" do
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:, line_ending: test_case[:line_ending]) }
context "with a valid file" do
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "is valid" do
expect(validator).to be_valid
end
end
end
end
context "when trying to upload different years data for 2023 bulk upload" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) }
context "with a valid file in an arbitrary order" do
let(:seed) { rand }
context "with a valid csv" do
let(:path) { file_fixture("2022_23_sales_bulk_upload.csv") }
it "is not valid" do
expect(validator).not_to be_valid
end
end
context "with unix line endings" do
let(:fixture_path) { file_fixture("2022_23_sales_bulk_upload.csv") }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
string = File.read(fixture_path)
string.gsub!("\r\n", "\n")
file.write(string)
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
end
end
context "without headers" do
let(:log) { build(:sales_log, :completed) }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
Timecop.freeze(Time.utc(2022, 10, 3))
file.write(BulkUpload::SalesLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.close
end
after do
Timecop.unfreeze
end
it "is not valid" do
expect(validator).not_to be_valid
end
before do
file.write(log_to_csv.default_field_numbers_row(seed:))
file.write(log_to_csv.to_csv_row(seed:))
file.rewind
end
context "with headers" do
let(:file) { Tempfile.new }
let(:seed) { rand }
let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2022, 10, 10)) }
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:) }
let(:field_numbers) { log_to_csv.default_2023_field_numbers }
let(:field_values) { log_to_csv.to_2023_row }
before do
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end
it "is not valid" do
expect(validator).not_to be_valid
end
it "is valid" do
expect(validator).to be_valid
end
end
context "when file is missing required headers" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2024) }
let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2024, 5, 5)) }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
file.write(BulkUpload::SalesLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2024_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
it "is not valid" do
expect(validator).not_to be_valid
expect(validator.errors["base"]).to include(match("Your file does not contain the required header rows."))
end
end
end
describe "#call" do
context "when a valid csv" do
let(:path) { file_fixture("2023_24_sales_bulk_upload_invalid.csv") }
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "does not create validation errors" do
expect { validator.call }.not_to change(BulkUploadError, :count)
end
end
context "with an invalid 2024 csv" do
before do
log.owning_organisation = nil
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
@ -227,41 +134,55 @@ RSpec.describe BulkUpload::Sales::Validator do
it "create validation error with correct values" do
validator.call
error = BulkUploadError.find_by(row: "9", field: "field_1", category: "setup")
error = BulkUploadError.find_by(row: "2", field: "field_1", category: "setup")
expect(error.field).to eql("field_1")
expect(error.error).to eql("You must answer owning organisation")
expect(error.purchaser_code).to eql("23 test BU")
expect(error.row).to eql("9")
expect(error.cell).to eql("B9")
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")
end
end
context "with unix line endings" do
let(:fixture_path) { file_fixture("2023_24_sales_bulk_upload.csv") }
let(:file) { Tempfile.new }
let(:path) { file.path }
[
{ line_ending: "\n", name: "unix" },
{ line_ending: "\r\n", name: "windows" },
].each do |test_case|
context "with #{test_case[:name]} line endings" do
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:, line_ending: test_case[:line_ending]) }
context "with a valid file" do
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "does not create validation errors" do
expect { validator.call }.not_to change(BulkUploadError, :count)
end
end
context "with an invalid file" do
let(:log) { build(:sales_log, :completed, assigned_to: user, privacynotice: nil) }
before do
string = File.read(fixture_path)
string.gsub!("\r\n", "\n")
file.write(string)
file.rewind
end
before do
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.rewind
end
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count)
end
end
end
end
context "without headers" do
let(:log) { build(:sales_log, :completed) }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do
file.write(BulkUpload::SalesLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
@ -271,13 +192,9 @@ RSpec.describe BulkUpload::Sales::Validator do
end
context "when duplicate rows present" do
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) { build(:sales_log, :completed) }
before do
file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2023_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2023_csv_row)
file.write(log_to_csv.to_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
@ -288,83 +205,62 @@ RSpec.describe BulkUpload::Sales::Validator do
end
describe "#create_logs?" do
around do |example|
Timecop.freeze(Time.zone.local(2023, 10, 22)) do
Singleton.__init__(FormHandler)
example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
context "when all logs are valid" do
let(:target_path) { file_fixture("2023_24_sales_bulk_upload.csv") }
let(:log_1) { build(:sales_log, :completed, assigned_to: user) }
let(:log_2) { build(:sales_log, :completed, assigned_to: user) }
it "returns truthy" do
validator.call
expect(validator).to be_create_logs
before do
file.write(BulkUpload::SalesLogToCsv.new(log: log_1).to_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
end
end
context "when there is an invalid log" do
let(:path) { file_fixture("2023_24_sales_bulk_upload_invalid.csv") }
it "returns falsey" do
it "returns truthy" do
validator.call
expect(validator).not_to be_create_logs
expect(validator).to be_create_logs
end
end
context "when a log is not valid?" do
context "when a log has a clearable non-setup error" do
let(:log_1) { build(:sales_log, :completed, assigned_to: user) }
let(:log_2) { build(:sales_log, :completed, assigned_to: user) }
let(:log_2) { build(:sales_log, :completed, assigned_to: user, age1: 5) }
before do
file.write(BulkUpload::SalesLogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_2, line_ending: "\r\n", col_offset: 0, overrides: { organisation_id: "random" }).to_2023_csv_row)
file.close
end
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
file.write(BulkUpload::SalesLogToCsv.new(log: log_1).to_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
end
end
context "when all logs valid?" do
let(:path) { file_fixture("2023_24_sales_bulk_upload.csv") }
it "returns true" do
it "returns truthy" do
validator.call
expect(validator).to be_create_logs
end
end
context "when a single log wants to block log creation" do
let(:unaffiliated_org) { create(:organisation) }
let(:log_1) { build(:sales_log, :completed, assigned_to: user, owning_organisation: unaffiliated_org) }
context "when a log has an incomplete setup section" do
let(:log_1) { build(:sales_log, :completed, assigned_to: user) }
let(:log_2) { build(:sales_log, :completed, assigned_to: user, privacynotice: nil) }
before do
file.write(BulkUpload::SalesLogToCsv.new(log: log_1, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_1).to_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
file.close
end
it "will not create logs" do
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
end
end
context "when a log has incomplete setup secion" do
let(:log) { build(:sales_log, assigned_to: user, saledate: Time.zone.local(2022, 5, 1)) }
context "when a single log wants to block log creation" do
let(:unaffiliated_org) { create(:organisation) }
let(:log) { build(:sales_log, :completed, assigned_to: user, owning_organisation: unaffiliated_org) }
before do
file.write(BulkUpload::SalesLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2023_csv_row)
file.write(log_to_csv.to_csv_row)
file.close
end
it "returns false" do
it "will not create logs" do
validator.call
expect(validator).not_to be_create_logs
end
@ -372,28 +268,20 @@ RSpec.describe BulkUpload::Sales::Validator do
end
describe "#total_logs_count?" do
around do |example|
Timecop.freeze(Time.zone.local(2023, 10, 22)) do
Singleton.__init__(FormHandler)
example.run
end
Timecop.return
Singleton.__init__(FormHandler)
end
context "when all logs are valid" do
let(:target_path) { file_fixture("2023_24_sales_bulk_upload.csv") }
let(:log_2) { build(:sales_log, :completed, assigned_to: user) }
let(:log_3) { build(:sales_log, :completed, assigned_to: user) }
before do
target_array = File.open(target_path).readlines
target_array[0..118].each do |line|
file.write line
end
file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log: log_3).to_csv_row)
file.rewind
end
it "returns correct total logs count" do
expect(validator.total_logs_count).to be(1)
expect(validator.total_logs_count).to be(3)
end
end
end

2
spec/services/csv/sales_log_csv_service_spec.rb

@ -30,6 +30,8 @@ RSpec.describe Csv::SalesLogCsvService do
county_as_entered: "county as entered",
postcode_full_as_entered: "AB1 2CD",
la_as_entered: "la as entered",
hhregres: 1,
hhregresstill: 4,
)
end
let(:service) { described_class.new(user:, export_type: "labels", year:) }

94
spec/support/bulk_upload/lettings_log_to_csv.rb

@ -12,6 +12,62 @@ class BulkUpload::LettingsLogToCsv
[nil] * col_offset
end
def to_csv_row(seed: nil)
year = log.collection_start_year
case year
when 2022
to_2022_csv_row(seed:)
when 2023
to_2023_csv_row(seed:)
when 2024
to_2024_csv_row(seed:)
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def to_row
year = log.collection_start_year
case year
when 2022
to_2022_row
when 2023
to_2023_row
when 2024
to_2024_row
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def default_field_numbers_row(seed: nil)
year = log.collection_start_year
case year
when 2022
default_2022_field_numbers_row(seed:)
when 2023
default_2023_field_numbers_row(seed:)
when 2024
default_2024_field_numbers_row(seed:)
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def default_field_numbers
year = log.collection_start_year
case year
when 2022
default_2022_field_numbers
when 2023
default_2023_field_numbers
when 2024
default_2024_field_numbers
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def to_2022_csv_row(seed: nil)
if seed
row = to_2022_row.shuffle(random: Random.new(seed))
@ -27,9 +83,9 @@ class BulkUpload::LettingsLogToCsv
def default_2022_field_numbers_row(seed: nil)
if seed
["Bulk upload field number"] + default_2022_field_numbers.shuffle(random: Random.new(seed))
["Field number"] + default_2022_field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + default_2022_field_numbers
["Field number"] + default_2022_field_numbers
end.flatten.join(",") + line_ending
end
@ -65,17 +121,17 @@ class BulkUpload::LettingsLogToCsv
def default_2023_field_numbers_row(seed: nil)
if seed
["Bulk upload field number"] + default_2023_field_numbers.shuffle(random: Random.new(seed))
["Field number"] + default_2023_field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + default_2023_field_numbers
["Field number"] + default_2023_field_numbers
end.flatten.join(",") + line_ending
end
def default_2024_field_numbers_row(seed: nil)
if seed
["Bulk upload field number"] + default_2024_field_numbers.shuffle(random: Random.new(seed))
["Field number"] + default_2024_field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + default_2024_field_numbers
["Field number"] + default_2024_field_numbers
end.flatten.join(",") + line_ending
end
@ -93,14 +149,14 @@ class BulkUpload::LettingsLogToCsv
log.managing_organisation&.old_visible_id,
log.assigned_to&.email,
log.needstype,
"S#{log.scheme&.id}",
log.scheme&.id ? "S#{log.scheme&.id}" : "",
log.location&.id,
renewal,
log.startdate&.day,
log.startdate&.month,
log.startdate&.strftime("%y"), # 10
london_affordable_rent,
rent_type,
log.irproduct_other,
log.tenancycode,
log.propcode,
@ -137,7 +193,7 @@ class BulkUpload::LettingsLogToCsv
log.age1 || overrides[:age1],
log.sex1,
log.ethnic,
log.national,
log.nationality_all_group,
log.ecstat1,
log.relat2,
log.age2 || overrides[:age2],
@ -214,11 +270,11 @@ class BulkUpload::LettingsLogToCsv
cbl,
chr,
cap,
nil, # accessible register
accessible_register,
log.referral,
net_income_known,
log.earnings,
log.incfreq,
log.earnings,
log.hb, # 120
log.benefits,
@ -385,16 +441,14 @@ class BulkUpload::LettingsLogToCsv
def custom_field_numbers_row(seed: nil, field_numbers: nil)
if seed
["Bulk upload field number"] + field_numbers.shuffle(random: Random.new(seed))
["Field number"] + field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + field_numbers
["Field number"] + field_numbers
end.flatten.join(",") + line_ending
end
def to_custom_csv_row(seed: nil, field_values: nil)
if seed
row = field_values.shuffle(random: Random.new(seed))
end
row = seed ? field_values.shuffle(random: Random.new(seed)) : field_values
(row_prefix + row).flatten.join(",") + line_ending
end
@ -422,6 +476,10 @@ private
end
end
def rent_type
LettingsLog::RENTTYPE_DETAIL_MAPPING[log.rent_type]
end
def leftreg
case log.leftreg
when 3
@ -471,6 +529,10 @@ private
checkbox_value(log.cap)
end
def accessible_register
checkbox_value(log.accessible_register)
end
def checkbox_value(field)
case field
when 0

92
spec/support/bulk_upload/sales_log_to_csv.rb

@ -12,6 +12,62 @@ class BulkUpload::SalesLogToCsv
[nil] * col_offset
end
def to_csv_row(seed: nil)
year = log.collection_start_year
case year
when 2022
to_2022_csv_row(seed:)
when 2023
to_2023_csv_row(seed:)
when 2024
to_2024_csv_row(seed:)
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def to_row
year = log.collection_start_year
case year
when 2022
to_2022_row
when 2023
to_2023_row
when 2024
to_2024_row
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def default_field_numbers_row(seed: nil)
year = log.collection_start_year
case year
when 2022
default_2022_field_numbers_row(seed:)
when 2023
default_2023_field_numbers_row(seed:)
when 2024
default_2024_field_numbers_row(seed:)
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def default_field_numbers
year = log.collection_start_year
case year
when 2022
default_2022_field_numbers
when 2023
default_2023_field_numbers
when 2024
default_2024_field_numbers
else
raise NotImplementedError "No mapping function implemented for year #{year}"
end
end
def to_2022_csv_row
(row_prefix + to_2022_row).flatten.join(",") + line_ending
end
@ -40,25 +96,25 @@ class BulkUpload::SalesLogToCsv
def default_2022_field_numbers_row(seed: nil)
if seed
["Bulk upload field number"] + default_2022_field_numbers.shuffle(random: Random.new(seed))
["Field number"] + default_2022_field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + default_2022_field_numbers
["Field number"] + default_2022_field_numbers
end.flatten.join(",") + line_ending
end
def default_2023_field_numbers_row(seed: nil)
if seed
["Bulk upload field number"] + default_2023_field_numbers.shuffle(random: Random.new(seed))
["Field number"] + default_2023_field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + default_2023_field_numbers
["Field number"] + default_2023_field_numbers
end.flatten.join(",") + line_ending
end
def default_2024_field_numbers_row(seed: nil)
if seed
["Bulk upload field number"] + default_2024_field_numbers.shuffle(random: Random.new(seed))
["Field number"] + default_2024_field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + default_2024_field_numbers
["Field number"] + default_2024_field_numbers
end.flatten.join(",") + line_ending
end
@ -239,10 +295,10 @@ class BulkUpload::SalesLogToCsv
log.saledate&.strftime("%y"),
log.purchid,
log.ownershipsch,
log.type, # field_9: "What is the type of shared ownership sale?",
log.type, # field_10: "What is the type of discounted ownership sale?",
log.ownershipsch == 1 ? log.type : "", # field_9: "What is the type of shared ownership sale?",
log.ownershipsch == 2 ? log.type : "", # field_10: "What is the type of discounted ownership sale?",
log.type, # field_11: "What is the type of outright sale?",
log.ownershipsch == 3 ? log.type : "", # field_11: "What is the type of outright sale?",
log.othtype,
log.companybuy,
log.buylivein,
@ -267,7 +323,7 @@ class BulkUpload::SalesLogToCsv
log.age1,
log.sex1,
log.ethnic,
log.national,
log.nationality_all_group,
log.ecstat1,
log.buy1livein,
log.relat2,
@ -275,7 +331,7 @@ class BulkUpload::SalesLogToCsv
log.sex2,
log.ethnic_group2, # 40
log.nationalbuy2,
log.nationality_all_buyer2_group,
log.ecstat2,
log.buy2livein,
log.hholdcount,
@ -309,7 +365,7 @@ class BulkUpload::SalesLogToCsv
log.buy2living, # 70
log.prevtenbuy2,
hhregres,
log.hhregres,
log.hhregresstill,
log.armedforcesspouse,
log.disabled,
@ -320,7 +376,7 @@ class BulkUpload::SalesLogToCsv
log.inc2mort, # 80
log.hb,
log.savings,
log.savings.present? || "R",
log.prevown,
log.prevshared,
log.proplen,
@ -357,7 +413,7 @@ class BulkUpload::SalesLogToCsv
log.proplen,
log.value,
log.grant,
log.discount,
log.discount || 0,
log.mortgageused,
log.mortgage,
log.mortgagelender,
@ -383,16 +439,14 @@ class BulkUpload::SalesLogToCsv
def custom_field_numbers_row(seed: nil, field_numbers: nil)
if seed
["Bulk upload field number"] + field_numbers.shuffle(random: Random.new(seed))
["Field number"] + field_numbers.shuffle(random: Random.new(seed))
else
["Bulk upload field number"] + field_numbers
["Field number"] + field_numbers
end.flatten.join(",") + line_ending
end
def to_custom_csv_row(seed: nil, field_values: nil)
if seed
row = field_values.shuffle(random: Random.new(seed))
end
row = seed ? field_values.shuffle(random: Random.new(seed)) : field_values
(row_prefix + row).flatten.join(",") + line_ending
end

Loading…
Cancel
Save