Browse Source

feat: fix lettings log import service

pull/1378/head
natdeanlewissoftwire 3 years ago
parent
commit
4a4ae25f10
  1. 734
      spec/services/imports/lettings_logs_import_service_spec.rb

734
spec/services/imports/lettings_logs_import_service_spec.rb

@ -1,348 +1,333 @@
require "rails_helper" require "rails_helper"
RSpec.describe Imports::LettingsLogsImportService do RSpec.describe Imports::LettingsLogsImportService do
subject(:lettings_log_service) { described_class.new(storage_service, logger) } context "in 21/22" do
around do |example|
let(:storage_service) { instance_double(Storage::S3Service) } Timecop.freeze(Time.zone.local(2022, 1, 1)) do
let(:logger) { instance_double(ActiveSupport::Logger) } Singleton.__init__(FormHandler)
example.run
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } end
let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") } Timecop.return
let(:fixture_directory) { "spec/fixtures/imports/logs" } Singleton.__init__(FormHandler)
end
let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") }
let(:managing_organisation) { FactoryBot.create(:organisation, old_visible_id: "2", provider_type: "PRP") }
let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) }
let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
end
before do
WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {})
allow(Organisation).to receive(:find_by).and_return(nil)
allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation)
allow(Organisation).to receive(:find_by).with(old_visible_id: managing_organisation.old_visible_id).and_return(managing_organisation)
# Created by users
FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:)
FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:)
# Location setup
FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1))
FactoryBot.create(:location, scheme_id: scheme1.id, startdate: Time.zone.local(2021, 4, 1))
FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1))
# Stub the form handler to use the real form subject(:lettings_log_service) { described_class.new(storage_service, logger) }
allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form)
allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2022_2023_form)
end
context "when importing lettings logs" do let(:storage_service) { instance_double(Storage::S3Service) }
let(:remote_folder) { "lettings_logs" } let(:logger) { instance_double(ActiveSupport::Logger) }
let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" }
let(:lettings_log_id2) { "166fc004-392e-47a8-acb8-1c018734882b" }
let(:lettings_log_id3) { "00d2343e-d5fa-4c89-8400-ec3854b0f2b4" }
let(:lettings_log_id4) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
let(:sales_log) { "shared_ownership_sales_log" }
before do let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") }
# Stub the S3 file listing and download let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") }
allow(storage_service).to receive(:list_files) let(:fixture_directory) { "spec/fixtures/imports/logs" }
.and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{lettings_log_id2}.xml #{remote_folder}/#{lettings_log_id3}.xml #{remote_folder}/#{lettings_log_id4}.xml #{remote_folder}/#{sales_log}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id}.xml")
.and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id2}.xml")
.and_return(open_file(fixture_directory, lettings_log_id2), open_file(fixture_directory, lettings_log_id2))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id3}.xml")
.and_return(open_file(fixture_directory, lettings_log_id3), open_file(fixture_directory, lettings_log_id3))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id4}.xml")
.and_return(open_file(fixture_directory, lettings_log_id4), open_file(fixture_directory, lettings_log_id4))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{sales_log}.xml")
.and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log))
end
it "successfully create all lettings logs" do let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") }
expect(logger).not_to receive(:error) let(:managing_organisation) { FactoryBot.create(:organisation, old_visible_id: "2", provider_type: "PRP") }
expect(logger).not_to receive(:warn) let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) }
expect(logger).not_to receive(:info) let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) }
expect { lettings_log_service.create_logs(remote_folder) }
.to change(LettingsLog, :count).by(4)
end
it "only updates existing lettings logs" do def open_file(directory, filename)
expect(logger).not_to receive(:error) File.open("#{directory}/#{filename}.xml")
expect(logger).not_to receive(:warn)
expect(logger).to receive(:info).with(/Updating lettings log/).exactly(4).times
expect { 2.times { lettings_log_service.create_logs(remote_folder) } }
.to change(LettingsLog, :count).by(4)
end end
it "creates organisation relationship once" do before do
expect(logger).not_to receive(:error) WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/)
expect(logger).not_to receive(:warn) .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {})
expect { lettings_log_service.create_logs(remote_folder) }
.to change(OrganisationRelationship, :count).by(1) allow(Organisation).to receive(:find_by).and_return(nil)
allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation)
allow(Organisation).to receive(:find_by).with(old_visible_id: managing_organisation.old_visible_id).and_return(managing_organisation)
# Created by users
FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:)
FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:)
# Location setup
FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1))
FactoryBot.create(:location, scheme_id: scheme1.id, startdate: Time.zone.local(2021, 4, 1))
FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1))
# Stub the form handler to use the real form
allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2021_2022_form)
allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form)
allow(FormHandler.instance).to receive(:get_form).with("next_lettings").and_return(real_2022_2023_form)
end end
context "when there are status discrepancies" do context "when importing lettings logs" do
let(:lettings_log_id5) { "893ufj2s-lq77-42m4-rty6-ej09gh585uy1" } let(:remote_folder) { "lettings_logs" }
let(:lettings_log_id6) { "5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd" } let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" }
let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id5) } let(:lettings_log_id2) { "166fc004-392e-47a8-acb8-1c018734882b" }
let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) } let(:lettings_log_id3) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
let(:sales_log) { "shared_ownership_sales_log" }
before do before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
.and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{lettings_log_id2}.xml #{remote_folder}/#{lettings_log_id3}.xml #{remote_folder}/#{sales_log}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id}.xml")
.and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id))
allow(storage_service).to receive(:get_file_io) allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id5}.xml") .with("#{remote_folder}/#{lettings_log_id2}.xml")
.and_return(open_file(fixture_directory, lettings_log_id5), open_file(fixture_directory, lettings_log_id5)) .and_return(open_file(fixture_directory, lettings_log_id2), open_file(fixture_directory, lettings_log_id2))
allow(storage_service).to receive(:get_file_io) allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id6}.xml") .with("#{remote_folder}/#{lettings_log_id3}.xml")
.and_return(open_file(fixture_directory, lettings_log_id6), open_file(fixture_directory, lettings_log_id6)) .and_return(open_file(fixture_directory, lettings_log_id3), open_file(fixture_directory, lettings_log_id3))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{sales_log}.xml")
.and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log))
end end
it "the logger logs a warning with the lettings log's old id/filename" do it "successfully create all lettings logs" do
expect(logger).to receive(:warn).with(/is not completed/).once expect(logger).not_to receive(:error)
expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id5} is incomplete but status should be complete/).once expect(logger).not_to receive(:warn)
expect(logger).not_to receive(:info)
lettings_log_service.send(:create_log, lettings_log_xml) expect { lettings_log_service.create_logs(remote_folder) }
.to change(LettingsLog, :count).by(3)
end end
it "on completion the ids of all logs with status discrepancies are logged in a warning" do it "only updates existing lettings logs" do
allow(storage_service).to receive(:list_files) expect(logger).not_to receive(:error)
.and_return(%W[#{remote_folder}/#{lettings_log_id5}.xml #{remote_folder}/#{lettings_log_id6}.xml]) expect(logger).not_to receive(:warn)
expect(logger).to receive(:warn).with(/is not completed/).twice expect(logger).to receive(:info).with(/Updating lettings log/).exactly(3).times
expect(logger).to receive(:warn).with(/is incomplete but status should be complete/).twice expect { 2.times { lettings_log_service.create_logs(remote_folder) } }
expect(logger).to receive(:warn).with(/The following lettings logs had status discrepancies: \[893ufj2s-lq77-42m4-rty6-ej09gh585uy1, 5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd\]/) .to change(LettingsLog, :count).by(3)
lettings_log_service.create_logs(remote_folder)
end end
end
end
context "when importing a specific log" do it "creates organisation relationship once" do
let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" } expect(logger).not_to receive(:error)
let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id) } expect(logger).not_to receive(:warn)
let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) } expect { lettings_log_service.create_logs(remote_folder) }
.to change(OrganisationRelationship, :count).by(1)
end
context "and the void date is after the start date" do context "when there are status discrepancies" do
before { lettings_log_xml.at_xpath("//xmlns:VYEAR").content = 2023 } let(:lettings_log_id5) { "893ufj2s-lq77-42m4-rty6-ej09gh585uy1" }
let(:lettings_log_id6) { "5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd" }
let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id5) }
let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) }
it "does not import the voiddate" do before do
expect(logger).to receive(:warn).with(/is not completed/) allow(storage_service).to receive(:get_file_io)
expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id} is incomplete but status should be complete/) .with("#{remote_folder}/#{lettings_log_id5}.xml")
.and_return(open_file(fixture_directory, lettings_log_id5), open_file(fixture_directory, lettings_log_id5))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id6}.xml")
.and_return(open_file(fixture_directory, lettings_log_id6), open_file(fixture_directory, lettings_log_id6))
end
lettings_log_service.send(:create_log, lettings_log_xml) it "the logger logs a warning with the lettings log's old id/filename" do
expect(logger).to receive(:warn).with(/is not completed/).once
expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id5} is incomplete but status should be complete/).once
lettings_log = LettingsLog.where(old_id: lettings_log_id).first lettings_log_service.send(:create_log, lettings_log_xml)
expect(lettings_log&.voiddate).to be_nil end
end
end
context "and the organisation legacy ID does not exist" do it "on completion the ids of all logs with status discrepancies are logged in a warning" do
before { lettings_log_xml.at_xpath("//xmlns:OWNINGORGID").content = 99_999 } allow(storage_service).to receive(:list_files)
.and_return(%W[#{remote_folder}/#{lettings_log_id5}.xml #{remote_folder}/#{lettings_log_id6}.xml])
expect(logger).to receive(:warn).with(/is not completed/).twice
expect(logger).to receive(:warn).with(/is incomplete but status should be complete/).twice
expect(logger).to receive(:warn).with(/The following lettings logs had status discrepancies: \[893ufj2s-lq77-42m4-rty6-ej09gh585uy1, 5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd\]/)
it "raises an exception" do lettings_log_service.create_logs(remote_folder)
expect { lettings_log_service.send(:create_log, lettings_log_xml) } end
.to raise_error(RuntimeError, "Organisation not found with legacy ID 99999")
end end
end end
context "and a person is under 16" do context "when importing a specific log" do
before { lettings_log_xml.at_xpath("//xmlns:P2Age").content = 14 } let(:lettings_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" }
let(:lettings_log_file) { open_file(fixture_directory, lettings_log_id) }
let(:lettings_log_xml) { Nokogiri::XML(lettings_log_file) }
context "when the economic status is set to refuse" do context "and the void date is after the start date" do
before { lettings_log_xml.at_xpath("//xmlns:P2Eco").content = "10) Refused" } before { lettings_log_xml.at_xpath("//xmlns:VYEAR").content = 2023 }
it "does not import the voiddate" do
expect(logger).to receive(:warn).with(/is not completed/)
expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id} is incomplete but status should be complete/)
it "sets the economic status to child under 16" do
# The update is done when calculating derived variables
expect(logger).to receive(:warn).with(/Differences found when saving log/)
lettings_log_service.send(:create_log, lettings_log_xml) lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.where(old_id: lettings_log_id).first lettings_log = LettingsLog.where(old_id: lettings_log_id).first
expect(lettings_log&.ecstat2).to be(9) expect(lettings_log&.voiddate).to be_nil
end end
end end
context "when the relationship to lead tenant is set to refuse" do context "and the organisation legacy ID does not exist" do
before { lettings_log_xml.at_xpath("//xmlns:P2Rel").content = "Refused" } before { lettings_log_xml.at_xpath("//xmlns:OWNINGORGID").content = 99_999 }
it "sets the relationship to lead tenant to child" do
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.where(old_id: lettings_log_id).first it "raises an exception" do
expect(lettings_log&.relat2).to eq("C") expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.to raise_error(RuntimeError, "Organisation not found with legacy ID 99999")
end end
end end
end
context "and this is an internal transfer that is in-progress with invalid answers" do context "and a person is under 16" do
before do before { lettings_log_xml.at_xpath("//xmlns:P2Age").content = 14 }
lettings_log_xml.at_xpath("//meta:status").content = "submitted-invalid"
lettings_log_xml.at_xpath("//xmlns:P2Age").content = 999
end
it "intercepts the relevant validation error" do context "when the economic status is set to refuse" do
expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Answer cannot be over 16/) before { lettings_log_xml.at_xpath("//xmlns:P2Eco").content = "10) Refused" }
expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Person 2’s age must be between/)
expect(logger).to receive(:warn).with(/Removing field ecstat2 from log triggering validation: Answer cannot be ‘child under 16’/)
expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error
end
it "clears out the invalid answers" do it "sets the economic status to child under 16" do
allow(logger).to receive(:warn) # The update is done when calculating derived variables
expect(logger).to receive(:warn).with(/Differences found when saving log/)
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log_service.send(:create_log, lettings_log_xml) lettings_log = LettingsLog.where(old_id: lettings_log_id).first
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) expect(lettings_log&.ecstat2).to be(9)
end
end
expect(lettings_log).not_to be_nil context "when the relationship to lead tenant is set to refuse" do
expect(lettings_log.age2).to be_nil before { lettings_log_xml.at_xpath("//xmlns:P2Rel").content = "Refused" }
expect(lettings_log.ecstat2).to be_nil
end
end
context "and it has zero earnings" do it "sets the relationship to lead tenant to child" do
before do lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log_xml.at_xpath("//meta:status").content = "submitted"
lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 0
end
it "intercepts the relevant validation error" do lettings_log = LettingsLog.where(old_id: lettings_log_id).first
expect(logger).to receive(:warn).with(/Where the income is 0, set earnings and income to blank and set incref to refused/) expect(lettings_log&.relat2).to eq("C")
expect { lettings_log_service.send(:create_log, lettings_log_xml) } end
.not_to raise_error end
end end
it "clears out the invalid answers" do context "and this is an internal transfer that is in-progress with invalid answers" do
allow(logger).to receive(:warn) before do
lettings_log_xml.at_xpath("//meta:status").content = "submitted-invalid"
lettings_log_xml.at_xpath("//xmlns:P2Age").content = 999
end
lettings_log_service.send(:create_log, lettings_log_xml) it "intercepts the relevant validation error" do
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Answer cannot be over 16/)
expect(logger).to receive(:warn).with(/Removing field age2 from log triggering validation: Person 2’s age must be between/)
expect(logger).to receive(:warn).with(/Removing field ecstat2 from log triggering validation: Answer cannot be ‘child under 16’/)
expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error
end
expect(lettings_log).not_to be_nil it "clears out the invalid answers" do
expect(lettings_log.earnings).to be_nil allow(logger).to receive(:warn)
expect(lettings_log.incref).to eq(1)
expect(lettings_log.net_income_known).to eq(2)
end
end
context "and an invalid tenancy length for tenancy type" do lettings_log_service.send(:create_log, lettings_log_xml)
before do lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
lettings_log_xml.at_xpath("//meta:status").content = "submitted"
lettings_log_xml.at_xpath("//xmlns:_2cYears").content = "1"
lettings_log_xml.at_xpath("//xmlns:Q2b").content = "4"
end
it "intercepts the relevant validation error" do expect(lettings_log).not_to be_nil
expect(logger).to receive(:warn).with(/Removing tenancylength as invalid/) expect(lettings_log.age2).to be_nil
expect { lettings_log_service.send(:create_log, lettings_log_xml) } expect(lettings_log.ecstat2).to be_nil
.not_to raise_error end
end end
it "clears out the invalid answers" do context "and it has zero earnings" do
allow(logger).to receive(:warn) before do
lettings_log_xml.at_xpath("//meta:status").content = "submitted"
lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 0
end
lettings_log_service.send(:create_log, lettings_log_xml) it "intercepts the relevant validation error" do
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) expect(logger).to receive(:warn).with(/Where the income is 0, set earnings and income to blank and set incref to refused/)
expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error
end
expect(lettings_log).not_to be_nil it "clears out the invalid answers" do
expect(lettings_log.tenancylength).to be_nil allow(logger).to receive(:warn)
expect(lettings_log.tenancy).to be_nil
end
end
context "and an lead tenant must be under 20 if childrens home or foster care" do lettings_log_service.send(:create_log, lettings_log_xml)
before do lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
lettings_log_xml.at_xpath("//meta:status").content = "submitted"
lettings_log_xml.at_xpath("//xmlns:Q11").content = "13"
lettings_log_xml.at_xpath("//xmlns:P1Age").content = "22"
end
it "intercepts the relevant validation error" do expect(lettings_log).not_to be_nil
expect(logger).to receive(:warn).with(/Removing age1 and prevten as incompatible/) expect(lettings_log.earnings).to be_nil
expect { lettings_log_service.send(:create_log, lettings_log_xml) } expect(lettings_log.incref).to eq(1)
.not_to raise_error expect(lettings_log.net_income_known).to eq(2)
end
end end
it "clears out the invalid answers" do context "and an invalid tenancy length for tenancy type" do
allow(logger).to receive(:warn) before do
lettings_log_xml.at_xpath("//meta:status").content = "submitted"
lettings_log_xml.at_xpath("//xmlns:_2cYears").content = "1"
lettings_log_xml.at_xpath("//xmlns:Q2b").content = "4"
end
lettings_log_service.send(:create_log, lettings_log_xml) it "intercepts the relevant validation error" do
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) expect(logger).to receive(:warn).with(/Removing tenancylength as invalid/)
expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error
end
expect(lettings_log).not_to be_nil it "clears out the invalid answers" do
expect(lettings_log.age1).to be_nil allow(logger).to receive(:warn)
expect(lettings_log.prevten).to be_nil
end
end
context "and is a carehome but missing carehome charge" do lettings_log_service.send(:create_log, lettings_log_xml)
let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
before do expect(lettings_log).not_to be_nil
lettings_log_xml.at_xpath("//meta:status").content = "submitted" expect(lettings_log.tenancylength).to be_nil
lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id expect(lettings_log.tenancy).to be_nil
scheme2.update!(registered_under_care_act: 2) end
lettings_log_xml.at_xpath("//xmlns:Q18b").content = ""
end end
it "intercepts the relevant validation error" do context "and an lead tenant must be under 20 if childrens home or foster care" do
allow(logger).to receive(:warn) before do
lettings_log_xml.at_xpath("//meta:status").content = "submitted"
lettings_log_xml.at_xpath("//xmlns:Q11").content = "13"
lettings_log_xml.at_xpath("//xmlns:P1Age").content = "22"
end
expect { lettings_log_service.send(:create_log, lettings_log_xml) } it "intercepts the relevant validation error" do
.not_to raise_error expect(logger).to receive(:warn).with(/Removing age1 and prevten as incompatible/)
end expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error
end
it "clears out the invalid answers" do it "clears out the invalid answers" do
allow(logger).to receive(:warn) allow(logger).to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml) lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log).not_to be_nil expect(lettings_log).not_to be_nil
expect(lettings_log.is_carehome).to be_truthy expect(lettings_log.age1).to be_nil
expect(lettings_log.chcharge).to be_nil expect(lettings_log.prevten).to be_nil
end
end end
end
context "and this is an internal transfer from a non social housing" do context "and is a carehome but missing carehome charge" do
before do let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
lettings_log_xml.at_xpath("//xmlns:Q11").content = "9 Residential care home"
lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer"
end
it "intercepts the relevant validation error" do before do
expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is a non social housing/) lettings_log_xml.at_xpath("//meta:status").content = "submitted"
expect { lettings_log_service.send(:create_log, lettings_log_xml) } lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id
.not_to raise_error scheme2.update!(registered_under_care_act: 2)
end lettings_log_xml.at_xpath("//xmlns:Q18b").content = ""
end
it "clears out the referral answer" do it "intercepts the relevant validation error" do
allow(logger).to receive(:warn) allow(logger).to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml) expect { lettings_log_service.send(:create_log, lettings_log_xml) }
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) .not_to raise_error
end
it "clears out the invalid answers" do
allow(logger).to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log).not_to be_nil expect(lettings_log).not_to be_nil
expect(lettings_log.referral).to be_nil expect(lettings_log.is_carehome).to be_truthy
expect(lettings_log.chcharge).to be_nil
end
end end
context "and this is an internal transfer from a previous fixed term tenancy" do context "and this is an internal transfer from a non social housing" do
before do before do
lettings_log_xml.at_xpath("//xmlns:Q11").content = "30 Fixed term Local Authority General Needs tenancy" lettings_log_xml.at_xpath("//xmlns:Q11").content = "9 Residential care home"
lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer" lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer"
end end
it "intercepts the relevant validation error" do it "intercepts the relevant validation error" do
expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is fixed terms or lifetime/) expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is a non social housing/)
expect { lettings_log_service.send(:create_log, lettings_log_xml) } expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error .not_to raise_error
end end
@ -356,87 +341,204 @@ RSpec.describe Imports::LettingsLogsImportService do
expect(lettings_log).not_to be_nil expect(lettings_log).not_to be_nil
expect(lettings_log.referral).to be_nil expect(lettings_log.referral).to be_nil
end end
context "and this is an internal transfer from a previous fixed term tenancy" do
before do
lettings_log_xml.at_xpath("//xmlns:Q11").content = "30 Fixed term Local Authority General Needs tenancy"
lettings_log_xml.at_xpath("//xmlns:Q16").content = "1 Internal Transfer"
end
it "intercepts the relevant validation error" do
expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is fixed terms or lifetime/)
expect { lettings_log_service.send(:create_log, lettings_log_xml) }
.not_to raise_error
end
it "clears out the referral answer" do
allow(logger).to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log).not_to be_nil
expect(lettings_log.referral).to be_nil
end
end
end end
end
context "and the net income soft validation is triggered (net_income_value_check)" do context "and the net income soft validation is triggered (net_income_value_check)" do
before do before do
lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly" lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly"
lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 890.00 lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 890.00
end
it "completes the log" do
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log.status).to eq("completed")
end
end end
it "completes the log" do context "and the rent soft validation is triggered (rent_value_check)" do
lettings_log_service.send(:create_log, lettings_log_xml) before do
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) lettings_log_xml.at_xpath("//xmlns:Q18ai").content = 200.00
expect(lettings_log.status).to eq("completed") lettings_log_xml.at_xpath("//xmlns:Q18av").content = 232.02
lettings_log_xml.at_xpath("//xmlns:Q17").content = "1 Weekly for 52 weeks"
LaRentRange.create!(
start_year: 2021,
la: "E08000035",
beds: 2,
lettype: 1,
soft_max: 900,
hard_max: 1500,
soft_min: 500,
hard_min: 100,
)
end
it "completes the log" do
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log.status).to eq("completed")
end
end end
end
context "and the rent soft validation is triggered (rent_value_check)" do context "and the retirement soft validation is triggered (retirement_value_check)" do
before do before do
lettings_log_xml.at_xpath("//xmlns:Q18ai").content = 200.00 lettings_log_xml.at_xpath("//xmlns:P1Age").content = 68
lettings_log_xml.at_xpath("//xmlns:Q18av").content = 232.02 lettings_log_xml.at_xpath("//xmlns:P1Eco").content = "6) Not Seeking Work"
lettings_log_xml.at_xpath("//xmlns:Q17").content = "1 Weekly for 52 weeks" end
LaRentRange.create!(
start_year: 2021, it "completes the log" do
la: "E08000035", lettings_log_service.send(:create_log, lettings_log_xml)
beds: 2, lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
lettype: 1, expect(lettings_log.status).to eq("completed")
soft_max: 900, end
hard_max: 1500,
soft_min: 500,
hard_min: 100,
)
end end
it "completes the log" do context "and this is a supported housing log with multiple locations under a scheme" do
lettings_log_service.send(:create_log, lettings_log_xml) let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log.status).to eq("completed") it "sets the scheme and location values" do
expect(logger).not_to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log.scheme_id).not_to be_nil
expect(lettings_log.location_id).not_to be_nil
expect(lettings_log.status).to eq("completed")
end
end end
end
context "and the retirement soft validation is triggered (retirement_value_check)" do context "and this is a supported housing log with a single location under a scheme" do
before do let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
lettings_log_xml.at_xpath("//xmlns:P1Age").content = 68
lettings_log_xml.at_xpath("//xmlns:P1Eco").content = "6) Not Seeking Work" before { lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id }
it "sets the scheme and location values" do
expect(logger).not_to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log.scheme_id).not_to be_nil
expect(lettings_log.location_id).not_to be_nil
expect(lettings_log.status).to eq("completed")
end
end end
end
end
it "completes the log" do context "in 22/23" do
lettings_log_service.send(:create_log, lettings_log_xml) around do |example|
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) Timecop.freeze(Time.zone.local(2023, 1, 1)) do
expect(lettings_log.status).to eq("completed") Singleton.__init__(FormHandler)
example.run
end end
Timecop.return
Singleton.__init__(FormHandler)
end end
context "and this is a supported housing log with multiple locations under a scheme" do subject(:lettings_log_service) { described_class.new(storage_service, logger) }
let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" }
it "sets the scheme and location values" do let(:storage_service) { instance_double(Storage::S3Service) }
expect(logger).not_to receive(:warn) let(:logger) { instance_double(ActiveSupport::Logger) }
lettings_log_service.send(:create_log, lettings_log_xml)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id)
expect(lettings_log.scheme_id).not_to be_nil let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") }
expect(lettings_log.location_id).not_to be_nil let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") }
expect(lettings_log.status).to eq("completed") let(:fixture_directory) { "spec/fixtures/imports/logs" }
end
let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") }
let(:managing_organisation) { FactoryBot.create(:organisation, old_visible_id: "2", provider_type: "PRP") }
let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: "0123", owning_organisation: organisation) }
let(:scheme2) { FactoryBot.create(:scheme, old_visible_id: "456", owning_organisation: organisation) }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
end end
context "and this is a supported housing log with a single location under a scheme" do before do
let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/)
.to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {})
allow(Organisation).to receive(:find_by).and_return(nil)
allow(Organisation).to receive(:find_by).with(old_visible_id: organisation.old_visible_id).and_return(organisation)
allow(Organisation).to receive(:find_by).with(old_visible_id: managing_organisation.old_visible_id).and_return(managing_organisation)
# Created by users
FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa", organisation:)
FactoryBot.create(:user, old_user_id: "e29c492473446dca4d50224f2bb7cf965a261d6f", organisation:)
# Location setup
FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme1.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1))
FactoryBot.create(:location, scheme_id: scheme1.id, startdate: Time.zone.local(2021, 4, 1))
FactoryBot.create(:location, old_visible_id: "10", postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W", startdate: Time.zone.local(2021, 4, 1))
# Stub the form handler to use the real form
allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2022_2023_form)
allow(FormHandler.instance).to receive(:get_form).with("previous_lettings").and_return(real_2021_2022_form)
allow(FormHandler.instance).to receive(:get_form).with("next_lettings").and_return(real_2022_2023_form)
end
before { lettings_log_xml.at_xpath("//xmlns:_1cmangroupcode").content = scheme2.old_visible_id } context "when importing lettings logs" do
let(:remote_folder) { "lettings_logs" }
let(:lettings_log_id) { "00d2343e-d5fa-4c89-8400-ec3854b0f2b4" }
let(:sales_log) { "shared_ownership_sales_log" }
it "sets the scheme and location values" do before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
.and_return(%W[#{remote_folder}/#{lettings_log_id}.xml #{remote_folder}/#{sales_log}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{lettings_log_id}.xml")
.and_return(open_file(fixture_directory, lettings_log_id), open_file(fixture_directory, lettings_log_id))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{sales_log}.xml")
.and_return(open_file(fixture_directory, sales_log), open_file(fixture_directory, sales_log))
end
it "successfully create all lettings logs" do
expect(logger).not_to receive(:error)
expect(logger).not_to receive(:warn) expect(logger).not_to receive(:warn)
lettings_log_service.send(:create_log, lettings_log_xml) expect(logger).not_to receive(:info)
lettings_log = LettingsLog.find_by(old_id: lettings_log_id) expect { lettings_log_service.create_logs(remote_folder) }
.to change(LettingsLog, :count).by(1)
end
expect(lettings_log.scheme_id).not_to be_nil it "only updates existing lettings logs" do
expect(lettings_log.location_id).not_to be_nil expect(logger).not_to receive(:error)
expect(lettings_log.status).to eq("completed") expect(logger).not_to receive(:warn)
expect(logger).to receive(:info).with(/Updating lettings log/).exactly(1).times
expect { 2.times { lettings_log_service.create_logs(remote_folder) } }
.to change(LettingsLog, :count).by(1)
end
it "creates organisation relationship once" do
expect(logger).not_to receive(:error)
expect(logger).not_to receive(:warn)
expect { lettings_log_service.create_logs(remote_folder) }
.to change(OrganisationRelationship, :count).by(1)
end end
end end
end end
end end

Loading…
Cancel
Save