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 8 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(:tenant_code) { SecureRandom.hex(4) }
let(:property_ref) { SecureRandom.hex(4) } let(:property_ref) { SecureRandom.hex(4) }
let(:purchaser_code) { nil } let(:purchaser_code) { nil }
let(:field) { :field_134 } let(:field) { :field_130 }
let(:error) { "some error" } let(:error) { "some error" }
let(:bulk_upload) { create(:bulk_upload, :lettings) } let(:bulk_upload) { create(:bulk_upload, :lettings) }
let(:bulk_upload_errors) do let(:bulk_upload_errors) do
@ -45,10 +45,28 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
expect(result).to have_content(expected) expect(result).to have_content(expected)
end end
it "renders the question for lettings" do context "when the bulk upload is for 2024" do
expected = "What do you expect the outstanding amount to be?" context "with a lettings bulk upload" do
result = render_inline(described_class.new(bulk_upload_errors:)) let(:bulk_upload) { build(:bulk_upload, :lettings, year: 2024) }
expect(result).to have_content(expected) 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 end
context "when tenant_code not present" do context "when tenant_code not present" do
@ -78,17 +96,6 @@ RSpec.describe BulkUploadErrorRowComponent, type: :component do
end end
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 it "renders the error" do
expected = error expected = error
result = render_inline(described_class.new(bulk_upload_errors:)) 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 factory :bulk_upload do
user user
log_type { BulkUpload.log_types.values.sample } 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 } identifier { SecureRandom.uuid }
sequence(:filename) { |n| "bulk-upload-#{n}.csv" } sequence(:filename) { |n| "bulk-upload-#{n}.csv" }
needstype { 1 } needstype { 1 }

3
spec/factories/sales_log.rb

@ -128,8 +128,7 @@ FactoryBot.define do
pregla { 1 } pregla { 1 }
pregother { 1 } pregother { 1 }
pregghb { 1 } pregghb { 1 }
hhregres { 1 } hhregres { 7 }
hhregresstill { 4 }
ppcodenk { 1 } ppcodenk { 1 }
prevten { 1 } prevten { 1 }
previous_la_known { 0 } 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, filename: bulk_upload.filename,
log_type: "lettings", log_type: "lettings",
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time), 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"), logs_link: clear_filters_url(filter_type: "lettings_logs"),
}, },
) )
@ -113,7 +113,7 @@ RSpec.describe BulkUploadMailer do
title: "Check your file data", title: "Check your file data",
filename: bulk_upload.filename, filename: bulk_upload.filename,
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time), 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"), 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 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 end

4
spec/models/form_handler_spec.rb

@ -246,8 +246,8 @@ RSpec.describe FormHandler do
end end
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 context "when only archived form is defined in JSON (current collection start year 2024 onwards)" do
let(:now) { Time.utc(2024, 9, 20) } 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 it "creates previous_lettings, current_lettings and next_lettings forms from ruby form objects and archived form from json" do
expect(form_handler.lettings_forms["archived_lettings"]).to be_present expect(form_handler.lettings_forms["archived_lettings"]).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) create_list(:location, 2, scheme: new_scheme)
end 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 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) } 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") expect(record_from_db["la"]).to eq("E08000003")
end 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 context "with 24/25 logs" do
let(:address_sales_log_24_25) do let(:address_sales_log_24_25) do
described_class.create({ 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 context "when buying in a non london borough" do
before do before do
record.update!(la: "E08000035") record.la = "E08000035"
record.reload
end end
it "adds errors if buyer 1 has income over 80,000" do 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 context "when buying in a london borough" do
before do before do
record.update!(la: "E09000030") record.la = "E09000030"
record.reload
end end
it "adds errors if buyer 1 has income over 90,000" do 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 context "when buyer 2 is not a child" do
before do before do
record.update!(ecstat2: rand(0..8)) record.ecstat2 = rand(0..8)
record.reload
end end
it "does not add an error if buyer 2 has an income" do it "does not add an error if buyer 2 has an income" do
record.ecstat2 = rand(0..8)
record.income2 = 40_000 record.income2 = 40_000
financial_validator.validate_child_income(record) financial_validator.validate_child_income(record)
expect(record.errors).to be_empty expect(record.errors).to be_empty
@ -324,30 +320,20 @@ RSpec.describe Validations::Sales::FinancialValidations do
end end
context "when buyer 2 is a child" do 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 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 record.income2 = 0
financial_validator.validate_child_income(record) financial_validator.validate_child_income(record)
expect(record.errors).to be_empty expect(record.errors).to be_empty
end end
it "adds errors if buyer 2 has an income" do 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 record.income2 = 40_000
financial_validator.validate_child_income(record) financial_validator.validate_child_income(record)
expect(record.errors["ecstat2"]).to include(match I18n.t("validations.financial.income.child_has_income")) 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")) expect(record.errors["income2"]).to include(match I18n.t("validations.financial.income.child_has_income"))
end 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
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" get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response).to be_successful 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 end
it "renders the bulk upload filename" do 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}" get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}"
expect(response).to be_successful 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 end
it "renders correct number of errors" do 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).to be_successful
expect(response.body).to include("Bulk upload for lettings") 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("View the error report")
expect(response.body).to include("How would you like to fix the errors?") expect(response.body).to include("How would you like to fix the errors?")
expect(response.body).to include(bulk_upload.filename) 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).to be_successful
expect(response.body).to include("Bulk upload for lettings") 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("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename) expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs") 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).to be_successful
expect(response.body).to include("Bulk upload for lettings") 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("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename) expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs") 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" 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("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("Check these 2 answers")
expect(response.body).to include(bulk_upload.filename) expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Are these fields correct?") 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}" get "/sales-logs/bulk-upload-results/#{bulk_upload.id}"
expect(response).to be_successful 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 end
it "renders correct number of errors" do 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).to be_successful
expect(response.body).to include("Bulk upload for sales") 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("View the error report")
expect(response.body).to include("How would you like to fix the errors?") expect(response.body).to include("How would you like to fix the errors?")
expect(response.body).to include(bulk_upload.filename) 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).to be_successful
expect(response.body).to include("Bulk upload for sales") 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("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename) expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs") 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).to be_successful
expect(response.body).to include("Bulk upload for sales") 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("These 2 answers will be deleted if you upload the log")
expect(response.body).to include(bulk_upload.filename) expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Clear this data and upload the logs") 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" 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("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("Check these 2 answers")
expect(response.body).to include(bulk_upload.filename) expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Are these fields correct?") 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
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(:sales_log) { create(:sales_log, owning_organisation: organisation, managing_organisation:, assigned_to: user) }
let(:params) do let(:params) do
{ {
@ -1034,10 +1034,10 @@ RSpec.describe FormController, type: :request do
before do before do
organisation.managing_agents << managing_organisation organisation.managing_agents << managing_organisation
organisation.reload 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.save!(validate: false)
sales_log.reload sales_log.reload
Timecop.freeze(Time.zone.local(2024, 12, 1)) Timecop.freeze(Time.zone.local(2024, 5, 1))
Singleton.__init__(FormHandler) Singleton.__init__(FormHandler)
end 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(:owning_org) { create(:organisation, old_visible_id: 123, rent_periods: [2]) }
let(:user) { create(:user, organisation: owning_org) } let(:user) { create(:user, organisation: owning_org) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:) } let(:bulk_upload) { create(:bulk_upload, :lettings, user:, year: 2024) }
let(:csv_parser) { instance_double(BulkUpload::Lettings::Year2023::CsvParser) } let(:csv_parser) { instance_double(BulkUpload::Lettings::Year2024::CsvParser) }
let(:row_parser) { instance_double(BulkUpload::Lettings::Year2023::RowParser) } 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) } let(:log) { build(:lettings_log, :completed, assigned_to: user, owning_organisation: owning_org, managing_organisation: owning_org) }
before do 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(csv_parser).to receive(:row_parsers).and_return([row_parser])
allow(row_parser).to receive(:log).and_return(log) allow(row_parser).to receive(:log).and_return(log)
allow(row_parser).to receive(:bulk_upload=).and_return(true) 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) allow(row_parser).to receive(:blank_row?).and_return(false)
end end
around do |example|
Timecop.freeze(Time.zone.local(2023, 4, 1)) do
Singleton.__init__(FormHandler)
example.run
end
end
describe "#call" do 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 context "when a valid csv with new log" do
it "creates a new log" do it "creates a new log" do
expect { service.call }.to change(LettingsLog, :count) expect { service.call }.to change(LettingsLog, :count)
@ -77,17 +61,11 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
build( build(
:lettings_log, :lettings_log,
:completed, :completed,
renttype: 3,
age1_known: 0, age1_known: 0,
age1: 5, age1: 5,
owning_organisation: owning_org, owning_organisation: owning_org,
managing_organisation: owning_org, managing_organisation: owning_org,
assigned_to: user, assigned_to: user,
national: 18,
waityear: 9,
joint: 2,
tenancy: 9,
ppcodenk: 1,
) )
end end
@ -148,18 +126,12 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
build( build(
:lettings_log, :lettings_log,
:completed, :completed,
renttype: 3,
age1: 22, age1: 22,
age1_known: 0, age1_known: 0,
ecstat1: 5, ecstat1: 5,
owning_organisation: owning_org, owning_organisation: owning_org,
managing_organisation: owning_org, managing_organisation: owning_org,
assigned_to: user, assigned_to: user,
national: 18,
waityear: 9,
joint: 2,
tenancy: 9,
ppcodenk: 1,
) )
end end

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

@ -3,186 +3,110 @@ require "rails_helper"
RSpec.describe BulkUpload::Lettings::Validator do RSpec.describe BulkUpload::Lettings::Validator do
subject(:validator) { described_class.new(bulk_upload:, path:) } 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(:user) { create(:user, organisation:) }
let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2024, 3, 3)) } let(:log) { build(:lettings_log, :completed, period: 2, assigned_to: user) }
let(:bulk_upload) { create(:bulk_upload, 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(:path) { file.path }
let(:file) { Tempfile.new } let(:file) { Tempfile.new }
describe "validations" do describe "validations" do
context "when 2023" do context "when file has headers" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) } context "and is empty" do
it "is not valid" do
context "when file has no headers" do expect(validator).not_to be_valid
context "and too many columns" do 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."])
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
end end
end end
context "when file has headers" do context "and file has extra invalid headers" do
context "and is empty" do let(:seed) { rand }
it "is not valid" do let(:field_numbers) { log_to_csv.default_field_numbers + %w[invalid_field_number] }
expect(validator).not_to be_valid let(:field_values) { log_to_csv.to_row + %w[value_for_invalid_field_number] }
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 before do
let(:seed) { rand } file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) } file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
let(:field_numbers) { log_to_csv.default_2023_field_numbers + %w[invalid_field_number] } file.rewind
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
end end
context "and file has too few valid headers" do it "is valid" do
let(:seed) { rand } expect(validator).to be_valid
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
end end
end
context "and file has too many valid headers" do context "and file has too few valid headers" do
let(:seed) { rand } let(:seed) { rand }
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) } let(:field_numbers) { log_to_csv.default_field_numbers }
let(:field_numbers) { log_to_csv.default_2023_field_numbers + %w[23] } let(:field_values) { log_to_csv.to_row }
let(:field_values) { log_to_csv.to_2023_row + %w[value] }
before do
before do field_numbers.delete_at(20)
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:)) field_values.delete_at(20)
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:)) file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
file.rewind file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
end file.rewind
end
it "is not valid" do it "is not valid" do
expect(validator).not_to be_valid expect(validator).not_to be_valid
expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"]) expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"])
end
end end
end end
context "when uploading a 2022 logs for 2023 bulk upload" do context "and file has too many valid headers" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) } let(:seed) { rand }
let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2022, 5, 6), tenancycode: "5") } let(:field_numbers) { log_to_csv.default_field_numbers + %w[23] }
let(:field_values) { log_to_csv.to_row + %w[value] }
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
it "is not valid" do before do
expect(validator).not_to be_valid file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
end file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end end
context "with headers" do it "is not valid" do
let(:seed) { rand } expect(validator).not_to be_valid
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) } expect(validator.errors["base"]).to eql(["Incorrect number of fields, please ensure you have used the correct template"])
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
end end
end end
end
context "when uploading a 2023 logs for 2024 bulk upload" do 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") }
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 context "with headers" do
before do let(:seed) { rand }
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n", col_offset: 0).to_2024_csv_row) let(:field_numbers) { log_to_csv.default_2024_field_numbers }
file.close let(:field_values) { log_to_csv.to_2024_row }
end
it "is not valid" do before do
expect(validator).not_to be_valid file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:))
end file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind
end end
context "with headers" do it "is not valid" do
let(:seed) { rand } expect(validator).not_to be_valid
let(:log_to_csv) { BulkUpload::LettingsLogToCsv.new(log:) } expect(validator.errors["base"]).to eql(["Incorrect start dates, please ensure you have used the correct template"])
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
end end
end end
end end
end end
describe "#call" do describe "#call" do
context "when a valid csv" do context "with an invalid 2024 csv" do
let(:path) { file_fixture("2023_24_lettings_bulk_upload_invalid.csv") } 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 it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count) 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 it "create validation error with correct values" do
validator.call 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.error).to eql("You must answer tenancy start date (day)")
expect(error.tenant_code).to eql("123") expect(error.tenant_code).to eql(log.tenancycode)
expect(error.property_ref).to be_nil expect(error.property_ref).to eql(log.propcode)
expect(error.row).to eql("9") expect(error.row).to eql("2")
expect(error.cell).to eql("H9") expect(error.cell).to eql("I2")
expect(error.col).to eql("H") expect(error.col).to eql("I")
end end
end end
context "with arbitrary ordered 23/24 csv" do context "with a valid csv" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) } before do
let(:log) { build(:lettings_log, :completed) } file.write(log_to_csv.default_field_numbers_row)
let(:file) { Tempfile.new } file.write(log_to_csv.to_csv_row)
let(:path) { file.path } file.rewind
let(:seed) { 321 } end
around do |example|
FormHandler.instance.use_real_forms!
example.run
FormHandler.instance.use_fake_forms! it "does not create validation errors" do
expect { validator.call }.not_to change(BulkUploadError, :count)
end 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 before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").default_2023_field_numbers_row(seed:)) log.needstype = nil
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row(seed:)) 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 file.close
end end
@ -231,59 +158,71 @@ RSpec.describe BulkUpload::Lettings::Validator do
it "create validation error with correct values" do it "create validation error with correct values" do
validator.call 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.field).to eql("field_4")
expect(error.error).to eql("You must answer letting type") expect(error.error).to eql("You must answer needs type")
expect(error.tenant_code).to eql(log.tenancycode) expect(error.tenant_code).to eql(log.tenancycode)
expect(error.property_ref).to eql(log.propcode) expect(error.property_ref).to eql(log.propcode)
expect(error.row).to eql("2") expect(error.row).to eql("2")
expect(error.cell).to eql("DD2") expect(error.cell).to eql("CY2")
expect(error.col).to eql("DD") expect(error.col).to eql("CY")
end end
end end
context "when duplicate rows present" do context "when duplicate rows present" do
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) { build(:lettings_log, :completed) }
before do before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").default_2023_field_numbers_row) file.write(log_to_csv.default_field_numbers_row)
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row) file.write(log_to_csv.to_csv_row)
file.write(BulkUpload::LettingsLogToCsv.new(log:, line_ending: "\r\n").to_2023_csv_row) file.write(log_to_csv.to_csv_row)
file.close file.close
end end
it "creates errors" do 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
end end
context "with unix line endings" do [
let(:fixture_path) { file_fixture("2023_24_lettings_bulk_upload.csv") } { line_ending: "\n", name: "unix" },
let(:file) { Tempfile.new } { line_ending: "\r\n", name: "windows" },
let(:path) { file.path } ].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 context "with a valid file" do
string = File.read(fixture_path) before do
string.gsub!("\r\n", "\n") file.write(log_to_csv.default_field_numbers_row)
file.write(string) file.write(log_to_csv.to_csv_row)
file.rewind file.rewind
end end
it "creates validation errors" do it "does not create validation errors" do
expect { validator.call }.to change(BulkUploadError, :count) 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
end end
context "without headers" do context "with a 2024 csv without headers" do
let(:log) { build(:lettings_log, :completed) } let(:log) { build(:lettings_log, :completed, startdate: Time.zone.local(2024, 7, 1), period: 2, assigned_to: user) }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do 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 file.close
end end
@ -294,47 +233,29 @@ RSpec.describe BulkUpload::Lettings::Validator do
end end
describe "#create_logs?" do describe "#create_logs?" do
context "when all logs are valid" do context "when a log has a clearable, non-setup error" do
let(:target_path) { file_fixture("2023_24_lettings_bulk_upload.csv") } 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) }
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) }
before do 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_1, col_offset: 0).to_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_2, col_offset: 0).to_csv_row)
file.close file.close
end end
it "returns false" do it "returns false" do
validator.call validator.call
expect(validator).not_to be_create_logs expect(validator).to be_create_logs
end end
end end
context "when all logs valid?" do context "when all logs valid?" do
let(:log_1) { 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, renttype: 1, assigned_to: user) } let(:log_2) { build(:lettings_log, :completed, period: 2, assigned_to: user) }
before do 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_1, col_offset: 0).to_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_2, col_offset: 0).to_csv_row)
file.close file.close
end end
@ -344,13 +265,13 @@ RSpec.describe BulkUpload::Lettings::Validator do
end end
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(: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 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 file.close
end end
@ -361,10 +282,10 @@ RSpec.describe BulkUpload::Lettings::Validator do
end end
context "when a log has incomplete setup section" do 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 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 file.close
end 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 RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
subject(:parser) { described_class.new(attributes) } 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(:attributes) { { bulk_upload: } }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: nil, year: 2023) } let(:bulk_upload) { create(:bulk_upload, :lettings, user:, needstype: nil, year: 2023) }
@ -30,7 +30,8 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
before do 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) create(:organisation_relationship, parent_organisation: owning_org, child_organisation: managing_org)
LaRentRange.create!( LaRentRange.create!(
@ -46,11 +47,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
) )
end end
around do |example| after do
Timecop.freeze(Date.new(2023, 10, 1)) do
FormHandler.instance.use_real_forms!
example.run
end
Timecop.return Timecop.return
end end
@ -369,7 +366,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when a supported housing log with chcharges already exists in the db" do 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 let(:attributes) do
valid_attributes.merge({ field_15: scheme.old_visible_id, valid_attributes.merge({ field_15: scheme.old_visible_id,
field_4: "2", field_4: "2",
@ -418,7 +415,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when a supported housing log different chcharges already exists in the db" do 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 let(:attributes) do
valid_attributes.merge({ field_15: scheme.old_visible_id, valid_attributes.merge({ field_15: scheme.old_visible_id,
field_4: "2", field_4: "2",
@ -513,7 +510,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when a supported housing log with chcharges already exists in the db" do 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 let(:attributes) do
valid_attributes.merge({ field_16: "S#{scheme.id}", valid_attributes.merge({ field_16: "S#{scheme.id}",
field_4: "2", field_4: "2",
@ -562,7 +559,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when a supported housing log different chcharges already exists in the db" do 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 let(:attributes) do
valid_attributes.merge({ field_16: "S#{scheme.id}", valid_attributes.merge({ field_16: "S#{scheme.id}",
field_4: "2", field_4: "2",
@ -901,7 +898,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when bulk upload is for supported housing" do 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 context "when general needs option selected" do
let(:attributes) { { bulk_upload:, field_5: "1", field_4: "2" } } let(:attributes) { { bulk_upload:, field_5: "1", field_4: "2" } }
@ -1374,7 +1371,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when 4 ie referred by LA and is not general needs" do 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" } } let(:attributes) { { bulk_upload:, field_119: "4", field_4: "2" } }
it "is permitted" do it "is permitted" do
@ -1411,9 +1408,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when inside of collection year" do 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 it "does not return errors" do
expect(parser.errors[:field_7]).not_to be_present expect(parser.errors[:field_7]).not_to be_present
@ -1423,15 +1420,9 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when outside of collection year" do 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(: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 it "returns setup errors" do
expect(parser.errors.where(:field_7, category: :setup)).to be_present expect(parser.errors.where(:field_7, category: :setup)).to be_present
@ -1640,7 +1631,7 @@ RSpec.describe BulkUpload::Lettings::Year2023::RowParser do
end end
context "when neither UPRN nor address fields are given for a supported housing record" do 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 let(:attributes) do
{ bulk_upload:, { bulk_upload:,
field_15: scheme.old_visible_id, 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(:bulk_upload) { create(:bulk_upload, :lettings, user:) }
let(:user) { create(:user, organisation: owning_org) } let(:user) { create(:user, organisation: owning_org) }
let(:owning_org) { create(:organisation, old_visible_id: 123, rent_periods: [2]) } let(:owning_org) { create(:organisation, old_visible_id: 123, rent_periods: [2]) }
let(:mock_validator) do let(:mock_validator) do
instance_double( instance_double(
BulkUpload::Lettings::Validator, BulkUpload::Lettings::Validator,
@ -13,20 +14,35 @@ RSpec.describe BulkUpload::Processor do
call: nil, call: nil,
total_logs_count: 1, total_logs_count: 1,
any_setup_errors?: false, 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 end
describe "#call" do let(:file) { Tempfile.new }
before do let(:path) { file.path }
Timecop.freeze(Time.zone.local(2023, 11, 10))
Singleton.__init__(FormHandler)
end
after do let(:log) { build(:lettings_log, :completed, assigned_to: user) }
Timecop.return
end
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 context "when errors exist from prior job run" do
let!(:existing_error) { create(:bulk_upload_error, bulk_upload:) } let!(:existing_error) { create(:bulk_upload_error, bulk_upload:) }
@ -38,15 +54,6 @@ RSpec.describe BulkUpload::Processor do
end end
context "when the bulk upload itself is not considered valid" do 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 let(:mock_validator) do
instance_double( instance_double(
BulkUpload::Lettings::Validator, BulkUpload::Lettings::Validator,
@ -57,11 +64,6 @@ RSpec.describe BulkUpload::Processor do
) )
end 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 it "sends failure email" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil) mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
@ -88,27 +90,7 @@ RSpec.describe BulkUpload::Processor do
end end
context "when the bulk upload processing throws an error" do 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 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) allow(mock_validator).to receive(:call).and_raise(StandardError)
end end
@ -132,16 +114,7 @@ RSpec.describe BulkUpload::Processor do
end end
end end
context "when a log has an incomplete setup section" do context "when a log has a setup 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 let(:mock_validator) do
instance_double( instance_double(
BulkUpload::Lettings::Validator, BulkUpload::Lettings::Validator,
@ -152,11 +125,6 @@ RSpec.describe BulkUpload::Processor do
) )
end 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 it "sends setup failure email" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil) mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
@ -170,37 +138,6 @@ RSpec.describe BulkUpload::Processor do
end end
context "when processing a bulk with perfect data" do 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 it "creates logs as not pending" do
expect { processor.call }.to change(LettingsLog.completed, :count).by(1) expect { processor.call }.to change(LettingsLog.completed, :count).by(1)
end end
@ -217,98 +154,10 @@ RSpec.describe BulkUpload::Processor do
end end
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 context "when a bulk upload has an in progress log" do
let(:mock_downloader) do let(:log) { build(:lettings_log, :setup_completed, assigned_to: user) }
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
before do 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(:create_logs?).and_return(true)
allow(mock_validator).to receive(:soft_validation_errors_only?).and_return(false) 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) allow(FeatureToggle).to receive(:bulk_upload_duplicate_log_check_enabled?).and_return(true)
@ -341,58 +190,12 @@ RSpec.describe BulkUpload::Processor do
end end
context "when a bulk upload has logs with only soft validations triggered" do 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 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(:create_logs?).and_return(true)
allow(mock_validator).to receive(:soft_validation_errors_only?).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) allow(FeatureToggle).to receive(:bulk_upload_duplicate_log_check_enabled?).and_return(true)
end end
after do
FormHandler.instance.use_fake_forms!
end
it "creates pending log" do it "creates pending log" do
expect { processor.call }.to change(LettingsLog.pending, :count).by(1) expect { processor.call }.to change(LettingsLog.pending, :count).by(1)
end end
@ -421,42 +224,18 @@ RSpec.describe BulkUpload::Processor do
end end
end end
context "when upload has no setup errors something blocks log creation" do context "when upload has something blocking log creation" do
let(:mock_downloader) do let(:mock_validator) do
instance_double( instance_double(
BulkUpload::Downloader, BulkUpload::Lettings::Validator,
invalid?: false,
call: nil, call: nil,
path:, total_logs_count: 1,
delete_local_file!: nil, any_setup_errors?: false,
) create_logs?: false,
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,
) )
end 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 it "sends correct_and_upload_again_mail" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil) mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
@ -471,12 +250,12 @@ RSpec.describe BulkUpload::Processor do
end end
describe "#approve" do 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 it "makes pending logs no longer pending" do
expect(log.status).to eql("pending") expect(log.status).to eql("pending")
processor.approve processor.approve
expect(log.reload.status).to eql("not_started") expect(log.reload.status).to eql("in_progress")
end end
end 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(:owning_org) { create(:organisation, old_visible_id: 123) }
let(:user) { create(:user, organisation: owning_org) } let(:user) { create(:user, organisation: owning_org) }
let(:bulk_upload) { create(:bulk_upload, :sales, user:) } let(:bulk_upload) { create(:bulk_upload, :sales, user:, year: 2024) }
let(:csv_parser) { instance_double(BulkUpload::Sales::Year2023::CsvParser) } let(:csv_parser) { instance_double(BulkUpload::Sales::Year2024::CsvParser) }
let(:row_parser) { instance_double(BulkUpload::Sales::Year2023::RowParser) } 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) } let(:log) { build(:sales_log, :completed, assigned_to: user, owning_organisation: owning_org, managing_organisation: owning_org) }
before do 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(csv_parser).to receive(:row_parsers).and_return([row_parser])
allow(row_parser).to receive(:log).and_return(log) allow(row_parser).to receive(:log).and_return(log)
allow(row_parser).to receive(:bulk_upload=).and_return(true) allow(row_parser).to receive(:bulk_upload=).and_return(true)
@ -21,13 +21,6 @@ RSpec.describe BulkUpload::Sales::LogCreator do
end end
describe "#call" do 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 context "when a valid csv with new log" do
it "creates a new log" do it "creates a new log" do
expect { service.call }.to change(SalesLog, :count) expect { service.call }.to change(SalesLog, :count)
@ -92,14 +85,15 @@ RSpec.describe BulkUpload::Sales::LogCreator do
build( build(
:sales_log, :sales_log,
:completed, :completed,
ownershipsch: 2,
pcodenk: 0,
ppcodenk: 0,
postcode_full: "AA11AA",
ppostcode_full: "BB22BB",
owning_organisation: owning_org, owning_organisation: owning_org,
assigned_to: user, assigned_to: user,
managing_organisation: owning_org, managing_organisation: owning_org,
ownershipsch: 2,
value: 200_000,
deposit: 10_000,
mortgageused: 1,
mortgage: 100_000,
grant: 10_000,
) )
end end
@ -111,10 +105,10 @@ RSpec.describe BulkUpload::Sales::LogCreator do
service.call service.call
record = SalesLog.last record = SalesLog.last
expect(record.pcodenk).to be_blank expect(record.value).to be_blank
expect(record.postcode_full).to be_blank expect(record.deposit).to be_blank
expect(record.ppcodenk).to be_blank expect(record.mortgage).to be_blank
expect(record.ppostcode_full).to be_blank expect(record.grant).to be_blank
end end
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(:user) { create(:user, organisation:) }
let(:organisation) { create(:organisation, old_visible_id: "123") } 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(:path) { file.path }
let(:file) { Tempfile.new } let(:file) { Tempfile.new }
@ -40,185 +42,90 @@ RSpec.describe BulkUpload::Sales::Validator do
end end
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(: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 before do
let(:path) { file_fixture("2022_23_sales_bulk_upload.csv") } file.write(log_to_csv.default_2024_field_numbers_row)
file.write(log_to_csv.to_2024_csv_row)
it "is not valid" do file.rewind
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
end end
context "with headers" do it "is not valid" do
let(:file) { Tempfile.new } expect(validator).not_to be_valid
let(:seed) { rand } expect(validator.errors["base"]).to eql(["Incorrect sale dates, please ensure you have used the correct template"])
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
end end
end end
context "when trying to upload 2024 year data for 2024 bulk upload" do [
let(:bulk_upload) { create(:bulk_upload, user:, year: 2024) } { line_ending: "\n", name: "unix" },
{ line_ending: "\r\n", name: "windows" },
context "with headers" do ].each do |test_case|
let(:file) { Tempfile.new } context "with #{test_case[:name]} line endings" do
let(:seed) { rand } let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:, line_ending: test_case[:line_ending]) }
let(:log) { build(:sales_log, :completed, saledate: Time.zone.local(2024, 10, 10)) }
let(:log_to_csv) { BulkUpload::SalesLogToCsv.new(log:) } context "with a valid file" do
let(:field_numbers) { log_to_csv.default_2024_field_numbers } before do
let(:field_values) { log_to_csv.to_2024_row } file.write(log_to_csv.default_field_numbers_row)
file.write(log_to_csv.to_csv_row)
before do file.rewind
file.write(log_to_csv.custom_field_numbers_row(seed:, field_numbers:)) end
file.write(log_to_csv.to_custom_csv_row(seed:, field_values:))
file.rewind it "is valid" do
end expect(validator).to be_valid
end
it "is valid" do
expect(validator).to be_valid
end end
end end
end end
context "when trying to upload different years data for 2023 bulk upload" do context "with a valid file in an arbitrary order" do
let(:bulk_upload) { create(:bulk_upload, user:, year: 2023) } let(:seed) { rand }
context "with a valid csv" do before do
let(:path) { file_fixture("2022_23_sales_bulk_upload.csv") } file.write(log_to_csv.default_field_numbers_row(seed:))
file.write(log_to_csv.to_csv_row(seed:))
it "is not valid" do file.rewind
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
end end
context "with headers" do it "is valid" do
let(:file) { Tempfile.new } expect(validator).to be_valid
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
end end
end end
context "when file is missing required headers" do 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 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 file.close
end end
it "is not valid" do it "is not valid" do
expect(validator).not_to be_valid 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 end
end end
describe "#call" do describe "#call" do
context "when a valid csv" 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 it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count) 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 it "create validation error with correct values" do
validator.call 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.field).to eql("field_1")
expect(error.error).to eql("You must answer owning organisation") expect(error.error).to eql("You must answer owning organisation")
expect(error.purchaser_code).to eql("23 test BU") expect(error.purchaser_code).to eql(log.purchaser_code)
expect(error.row).to eql("9") expect(error.row).to eql("2")
expect(error.cell).to eql("B9") expect(error.cell).to eql("B2")
expect(error.col).to eql("B") expect(error.col).to eql("B")
end end
end end
context "with unix line endings" do [
let(:fixture_path) { file_fixture("2023_24_sales_bulk_upload.csv") } { line_ending: "\n", name: "unix" },
let(:file) { Tempfile.new } { line_ending: "\r\n", name: "windows" },
let(:path) { file.path } ].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 before do
string = File.read(fixture_path) file.write(log_to_csv.default_field_numbers_row)
string.gsub!("\r\n", "\n") file.write(log_to_csv.to_csv_row)
file.write(string) file.rewind
file.rewind end
end
it "creates validation errors" do it "creates validation errors" do
expect { validator.call }.to change(BulkUploadError, :count) expect { validator.call }.to change(BulkUploadError, :count)
end
end
end end
end end
context "without headers" do context "without headers" do
let(:log) { build(:sales_log, :completed) }
let(:file) { Tempfile.new }
let(:path) { file.path }
before do 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 file.close
end end
@ -271,13 +192,9 @@ RSpec.describe BulkUpload::Sales::Validator do
end end
context "when duplicate rows present" do context "when duplicate rows present" do
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) { build(:sales_log, :completed) }
before do before do
file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2023_csv_row) file.write(log_to_csv.to_csv_row)
file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2023_csv_row) file.write(log_to_csv.to_csv_row)
file.close file.close
end end
@ -288,83 +205,62 @@ RSpec.describe BulkUpload::Sales::Validator do
end end
describe "#create_logs?" do 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 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 before do
validator.call file.write(BulkUpload::SalesLogToCsv.new(log: log_1).to_csv_row)
expect(validator).to be_create_logs file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
end 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 validator.call
expect(validator).not_to be_create_logs expect(validator).to be_create_logs
end end
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_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 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, line_ending: "\r\n", col_offset: 0, overrides: { organisation_id: "random" }).to_2023_csv_row) file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
file.close
end
it "returns false" do
validator.call
expect(validator).not_to be_create_logs
end 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 validator.call
expect(validator).to be_create_logs expect(validator).to be_create_logs
end end
end end
context "when a single log wants to block log creation" do context "when a log has an incomplete setup section" do
let(:unaffiliated_org) { create(:organisation) } let(:log_1) { build(:sales_log, :completed, assigned_to: user) }
let(:log_2) { build(:sales_log, :completed, assigned_to: user, privacynotice: nil) }
let(:log_1) { build(:sales_log, :completed, assigned_to: user, owning_organisation: unaffiliated_org) }
before do 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 file.close
end end
it "will not create logs" do it "returns false" do
validator.call validator.call
expect(validator).not_to be_create_logs expect(validator).not_to be_create_logs
end end
end end
context "when a log has incomplete setup secion" do context "when a single log wants to block log creation" do
let(:log) { build(:sales_log, assigned_to: user, saledate: Time.zone.local(2022, 5, 1)) } let(:unaffiliated_org) { create(:organisation) }
let(:log) { build(:sales_log, :completed, assigned_to: user, owning_organisation: unaffiliated_org) }
before do 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 file.close
end end
it "returns false" do it "will not create logs" do
validator.call validator.call
expect(validator).not_to be_create_logs expect(validator).not_to be_create_logs
end end
@ -372,28 +268,20 @@ RSpec.describe BulkUpload::Sales::Validator do
end end
describe "#total_logs_count?" do 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 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 before do
target_array = File.open(target_path).readlines file.write(log_to_csv.default_field_numbers_row)
target_array[0..118].each do |line| file.write(log_to_csv.to_csv_row)
file.write line file.write(BulkUpload::SalesLogToCsv.new(log: log_2).to_csv_row)
end file.write(BulkUpload::SalesLogToCsv.new(log: log_3).to_csv_row)
file.rewind file.rewind
end end
it "returns correct total logs count" do 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 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", county_as_entered: "county as entered",
postcode_full_as_entered: "AB1 2CD", postcode_full_as_entered: "AB1 2CD",
la_as_entered: "la as entered", la_as_entered: "la as entered",
hhregres: 1,
hhregresstill: 4,
) )
end end
let(:service) { described_class.new(user:, export_type: "labels", year:) } 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 [nil] * col_offset
end 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) def to_2022_csv_row(seed: nil)
if seed if seed
row = to_2022_row.shuffle(random: Random.new(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) def default_2022_field_numbers_row(seed: nil)
if seed 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 else
["Bulk upload field number"] + default_2022_field_numbers ["Field number"] + default_2022_field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
@ -65,17 +121,17 @@ class BulkUpload::LettingsLogToCsv
def default_2023_field_numbers_row(seed: nil) def default_2023_field_numbers_row(seed: nil)
if seed 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 else
["Bulk upload field number"] + default_2023_field_numbers ["Field number"] + default_2023_field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
def default_2024_field_numbers_row(seed: nil) def default_2024_field_numbers_row(seed: nil)
if seed 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 else
["Bulk upload field number"] + default_2024_field_numbers ["Field number"] + default_2024_field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
@ -93,14 +149,14 @@ class BulkUpload::LettingsLogToCsv
log.managing_organisation&.old_visible_id, log.managing_organisation&.old_visible_id,
log.assigned_to&.email, log.assigned_to&.email,
log.needstype, log.needstype,
"S#{log.scheme&.id}", log.scheme&.id ? "S#{log.scheme&.id}" : "",
log.location&.id, log.location&.id,
renewal, renewal,
log.startdate&.day, log.startdate&.day,
log.startdate&.month, log.startdate&.month,
log.startdate&.strftime("%y"), # 10 log.startdate&.strftime("%y"), # 10
london_affordable_rent, rent_type,
log.irproduct_other, log.irproduct_other,
log.tenancycode, log.tenancycode,
log.propcode, log.propcode,
@ -137,7 +193,7 @@ class BulkUpload::LettingsLogToCsv
log.age1 || overrides[:age1], log.age1 || overrides[:age1],
log.sex1, log.sex1,
log.ethnic, log.ethnic,
log.national, log.nationality_all_group,
log.ecstat1, log.ecstat1,
log.relat2, log.relat2,
log.age2 || overrides[:age2], log.age2 || overrides[:age2],
@ -214,11 +270,11 @@ class BulkUpload::LettingsLogToCsv
cbl, cbl,
chr, chr,
cap, cap,
nil, # accessible register accessible_register,
log.referral, log.referral,
net_income_known, net_income_known,
log.earnings,
log.incfreq, log.incfreq,
log.earnings,
log.hb, # 120 log.hb, # 120
log.benefits, log.benefits,
@ -385,16 +441,14 @@ class BulkUpload::LettingsLogToCsv
def custom_field_numbers_row(seed: nil, field_numbers: nil) def custom_field_numbers_row(seed: nil, field_numbers: nil)
if seed if seed
["Bulk upload field number"] + field_numbers.shuffle(random: Random.new(seed)) ["Field number"] + field_numbers.shuffle(random: Random.new(seed))
else else
["Bulk upload field number"] + field_numbers ["Field number"] + field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
def to_custom_csv_row(seed: nil, field_values: nil) def to_custom_csv_row(seed: nil, field_values: nil)
if seed row = seed ? field_values.shuffle(random: Random.new(seed)) : field_values
row = field_values.shuffle(random: Random.new(seed))
end
(row_prefix + row).flatten.join(",") + line_ending (row_prefix + row).flatten.join(",") + line_ending
end end
@ -422,6 +476,10 @@ private
end end
end end
def rent_type
LettingsLog::RENTTYPE_DETAIL_MAPPING[log.rent_type]
end
def leftreg def leftreg
case log.leftreg case log.leftreg
when 3 when 3
@ -471,6 +529,10 @@ private
checkbox_value(log.cap) checkbox_value(log.cap)
end end
def accessible_register
checkbox_value(log.accessible_register)
end
def checkbox_value(field) def checkbox_value(field)
case field case field
when 0 when 0

92
spec/support/bulk_upload/sales_log_to_csv.rb

@ -12,6 +12,62 @@ class BulkUpload::SalesLogToCsv
[nil] * col_offset [nil] * col_offset
end 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 def to_2022_csv_row
(row_prefix + to_2022_row).flatten.join(",") + line_ending (row_prefix + to_2022_row).flatten.join(",") + line_ending
end end
@ -40,25 +96,25 @@ class BulkUpload::SalesLogToCsv
def default_2022_field_numbers_row(seed: nil) def default_2022_field_numbers_row(seed: nil)
if seed 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 else
["Bulk upload field number"] + default_2022_field_numbers ["Field number"] + default_2022_field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
def default_2023_field_numbers_row(seed: nil) def default_2023_field_numbers_row(seed: nil)
if seed 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 else
["Bulk upload field number"] + default_2023_field_numbers ["Field number"] + default_2023_field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
def default_2024_field_numbers_row(seed: nil) def default_2024_field_numbers_row(seed: nil)
if seed 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 else
["Bulk upload field number"] + default_2024_field_numbers ["Field number"] + default_2024_field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
@ -239,10 +295,10 @@ class BulkUpload::SalesLogToCsv
log.saledate&.strftime("%y"), log.saledate&.strftime("%y"),
log.purchid, log.purchid,
log.ownershipsch, log.ownershipsch,
log.type, # field_9: "What is the type of shared ownership sale?", log.ownershipsch == 1 ? 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 == 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.othtype,
log.companybuy, log.companybuy,
log.buylivein, log.buylivein,
@ -267,7 +323,7 @@ class BulkUpload::SalesLogToCsv
log.age1, log.age1,
log.sex1, log.sex1,
log.ethnic, log.ethnic,
log.national, log.nationality_all_group,
log.ecstat1, log.ecstat1,
log.buy1livein, log.buy1livein,
log.relat2, log.relat2,
@ -275,7 +331,7 @@ class BulkUpload::SalesLogToCsv
log.sex2, log.sex2,
log.ethnic_group2, # 40 log.ethnic_group2, # 40
log.nationalbuy2, log.nationality_all_buyer2_group,
log.ecstat2, log.ecstat2,
log.buy2livein, log.buy2livein,
log.hholdcount, log.hholdcount,
@ -309,7 +365,7 @@ class BulkUpload::SalesLogToCsv
log.buy2living, # 70 log.buy2living, # 70
log.prevtenbuy2, log.prevtenbuy2,
hhregres, log.hhregres,
log.hhregresstill, log.hhregresstill,
log.armedforcesspouse, log.armedforcesspouse,
log.disabled, log.disabled,
@ -320,7 +376,7 @@ class BulkUpload::SalesLogToCsv
log.inc2mort, # 80 log.inc2mort, # 80
log.hb, log.hb,
log.savings, log.savings.present? || "R",
log.prevown, log.prevown,
log.prevshared, log.prevshared,
log.proplen, log.proplen,
@ -357,7 +413,7 @@ class BulkUpload::SalesLogToCsv
log.proplen, log.proplen,
log.value, log.value,
log.grant, log.grant,
log.discount, log.discount || 0,
log.mortgageused, log.mortgageused,
log.mortgage, log.mortgage,
log.mortgagelender, log.mortgagelender,
@ -383,16 +439,14 @@ class BulkUpload::SalesLogToCsv
def custom_field_numbers_row(seed: nil, field_numbers: nil) def custom_field_numbers_row(seed: nil, field_numbers: nil)
if seed if seed
["Bulk upload field number"] + field_numbers.shuffle(random: Random.new(seed)) ["Field number"] + field_numbers.shuffle(random: Random.new(seed))
else else
["Bulk upload field number"] + field_numbers ["Field number"] + field_numbers
end.flatten.join(",") + line_ending end.flatten.join(",") + line_ending
end end
def to_custom_csv_row(seed: nil, field_values: nil) def to_custom_csv_row(seed: nil, field_values: nil)
if seed row = seed ? field_values.shuffle(random: Random.new(seed)) : field_values
row = field_values.shuffle(random: Random.new(seed))
end
(row_prefix + row).flatten.join(",") + line_ending (row_prefix + row).flatten.join(",") + line_ending
end end

Loading…
Cancel
Save