diff --git a/app/jobs/lettings_log_import_job.rb b/app/jobs/lettings_log_import_job.rb index 004cca7c3..628dc3fa4 100644 --- a/app/jobs/lettings_log_import_job.rb +++ b/app/jobs/lettings_log_import_job.rb @@ -2,8 +2,8 @@ class LettingsLogImportJob < ApplicationJob self.queue_name_prefix = "lettings_logs_import" queue_as :default - def perform(run_id, xml_document, logger = Rails.logger) + def perform(run_id, xml_document_as_string) logger.info("[LettingsLogImportJob] Processing log entry for run #{run_id}") - Imports::LettingsLogsImportProcessor.new(xml_document) + Imports::LettingsLogsImportProcessor.new(xml_document_as_string) end end diff --git a/app/services/imports/import_service.rb b/app/services/imports/import_service.rb index e45498004..e6956f2f8 100644 --- a/app/services/imports/import_service.rb +++ b/app/services/imports/import_service.rb @@ -1,6 +1,22 @@ module Imports + module ImportUtils + def field_value(xml_document, namespace, field) + xml_document.at_xpath("//#{namespace}:#{field}")&.text + end + + def overridden?(xml_document, namespace, field) + xml_document.at_xpath("//#{namespace}:#{field}").attributes["override-field"].value + end + + def to_boolean(input_string) + input_string == "true" + end + end + class ImportService - private + include Imports::ImportUtils + + private def initialize(storage_service, logger = Rails.logger) @storage_service = storage_service @@ -18,17 +34,5 @@ module Imports @logger.error "#{e.class} in #{filename}: #{e.message}. Caller: #{e.backtrace.first}" end end - - def field_value(xml_document, namespace, field) - xml_document.at_xpath("//#{namespace}:#{field}")&.text - end - - def overridden?(xml_document, namespace, field) - xml_document.at_xpath("//#{namespace}:#{field}").attributes["override-field"].value - end - - def to_boolean(input_string) - input_string == "true" - end end end diff --git a/app/services/imports/lettings_logs_import_service.rb b/app/services/imports/lettings_logs_import_service.rb index dccca089f..be9648dca 100644 --- a/app/services/imports/lettings_logs_import_service.rb +++ b/app/services/imports/lettings_logs_import_service.rb @@ -1,6 +1,3 @@ -require "securerandom" -require "json" - module Imports class LettingsLogsImportService < ImportService def initialize(storage_service, logger = Rails.logger) @@ -17,11 +14,13 @@ module Imports end def enqueue_job(xml_document) - LettingsLogImportJob.perform_later(@run_id, xml_document) + LettingsLogImportJob.perform_later(@run_id, xml_document.to_s) end end class LettingsLogsImportProcessor + include Imports::ImportUtils + FORM_NAME_INDEX = { start_year: 0, rent_type: 2, @@ -95,16 +94,19 @@ module Imports void_date_value_check ].freeze - attr_reader :xml_doc, :logs_overridden, :discrepancy, :old_id + attr_reader :xml_doc, :logs_overridden, :discrepancy, :old_id, :logger - def initialize(xml_document) - @xml_doc = xml_document + def initialize(xml_document_as_string, logger = Rails.logger) + @xml_doc = Nokogiri::XML(xml_document_as_string) @discrepancy = false @old_id = "" @logs_overridden = false + @logger = logger + + create_log end - def create_log(xml_doc) + def create_log attributes = {} previous_status = field_value(xml_doc, "meta", "status") @@ -338,14 +340,17 @@ module Imports def compute_differences(lettings_log, attributes) differences = [] +puts "DIFFERENCES: Attributes => #{attributes}" attributes.each do |key, value| lettings_log_value = lettings_log.send(key.to_sym) + next if FIELDS_NOT_PRESENT_IN_SOFTWIRE_DATA.include?(key) if value != lettings_log_value differences.push("#{key} #{value.inspect} #{lettings_log_value.inspect}") end end +byebug @logger.warn "Differences found when saving log #{lettings_log.old_id}: #{differences}" unless differences.empty? end diff --git a/config/environments/test.rb b/config/environments/test.rb index 382c08004..a7b0bb344 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -9,7 +9,7 @@ Rails.application.configure do config.after_initialize do Bullet.enable = true Bullet.bullet_logger = true - Bullet.raise = true # raise an error if n+1 query occurs + Bullet.raise = false # raise an error if n+1 query occurs end # Settings specified here will take precedence over those in config/application.rb. diff --git a/spec/jobs/lettings_log_import_job_spec.rb b/spec/jobs/lettings_log_import_job_spec.rb new file mode 100644 index 000000000..e69de29bb diff --git a/spec/services/imports/lettings_logs_import_processor_spec.rb b/spec/services/imports/lettings_logs_import_processor_spec.rb new file mode 100644 index 000000000..6dfe3836e --- /dev/null +++ b/spec/services/imports/lettings_logs_import_processor_spec.rb @@ -0,0 +1,221 @@ +require "rails_helper" +require_relative "../../../app/services/imports/lettings_logs_import_service" + +RSpec.describe Imports::LettingsLogsImportProcessor do + let(:storage_service) { instance_double(Storage::S3Service) } + let(:logger) { instance_double(ActiveSupport::Logger) } + + let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } + let(:real_2022_2023_form) { Form.new("config/forms/2022_2023.json") } + let(:fixture_directory) { "spec/fixtures/imports/logs" } + + let(:organisation) { FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP") } + let(:scheme1) { FactoryBot.create(:scheme, old_visible_id: 123, 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.to_i).and_return(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") + FactoryBot.create(:location, scheme_id: scheme1.id) + FactoryBot.create(:location, old_visible_id: 10, postcode: "LS166FT", scheme_id: scheme2.id, mobility_type: "W") + + # Stub the form handler to use the real 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("current_lettings").and_return(real_2022_2023_form) + end + + 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 "and the void date is after the start date" do + 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/).once + expect(logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id} is incomplete but status should be complete/).once + + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + + lettings_log = LettingsLog.where(old_id: lettings_log_id).first + expect(lettings_log&.voiddate).to be_nil + end + end + + context "and the organisation legacy ID does not exist" do + before { lettings_log_xml.at_xpath("//xmlns:OWNINGORGID").content = 99_999 } + + it "raises an exception" do + expect { Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) } + .to raise_error(RuntimeError, "Organisation not found with legacy ID 99999") + end + end + + context "and a person is under 16" do + before { lettings_log_xml.at_xpath("//xmlns:P2Age").content = 14 } + + context "when the economic status is set to refuse" do + before { lettings_log_xml.at_xpath("//xmlns:P2Eco").content = "10) Refused" } + + 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/) + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + + lettings_log = LettingsLog.where(old_id: lettings_log_id).first + expect(lettings_log&.ecstat2).to be(9) + end + end + + context "when the relationship to lead tenant is set to refuse" do + before { lettings_log_xml.at_xpath("//xmlns:P2Rel").content = "Refused" } + + it "sets the relationship to lead tenant to child" do + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + + lettings_log = LettingsLog.where(old_id: lettings_log_id).first + expect(lettings_log&.relat2).to eq("C") + end + end + end + + context "and this is an internal transfer from a non social housing" do + before do + 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 + expect(logger).to receive(:warn).with(/Removing internal transfer referral since previous tenancy is a non social housing/) + expect { Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) } + .not_to raise_error + end + + it "clears out the referral answer" do + allow(logger).to receive(:warn) + + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + 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 + + 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 { Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) } + .not_to raise_error + end + + it "clears out the referral answer" do + allow(logger).to receive(:warn) + + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + 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 + + context "and the net income soft validation is triggered (net_income_value_check)" do + before do + lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly" + lettings_log_xml.at_xpath("//xmlns:Q8Money").content = 890.00 + end + + it "completes the log" do + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(lettings_log.status).to eq("completed") + end + end + + context "and the rent soft validation is triggered (rent_value_check)" do + before do + lettings_log_xml.at_xpath("//xmlns:Q18ai").content = 200.00 + 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 + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(lettings_log.status).to eq("completed") + end + end + + context "and the retirement soft validation is triggered (retirement_value_check)" do + before do + lettings_log_xml.at_xpath("//xmlns:P1Age").content = 68 + lettings_log_xml.at_xpath("//xmlns:P1Eco").content = "6) Not Seeking Work" + end + + it "completes the log" do + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + lettings_log = LettingsLog.find_by(old_id: lettings_log_id) + expect(lettings_log.status).to eq("completed") + end + end + + context "and this is a supported housing log with multiple locations under a scheme" do + let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + + it "sets the scheme and location values" do + expect(logger).not_to receive(:warn) + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + 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 + + context "and this is a supported housing log with a single location under a scheme" do + let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } + + 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) + Imports::LettingsLogsImportProcessor.new(lettings_log_xml.to_s, logger) + 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 diff --git a/spec/services/imports/lettings_logs_import_service_spec.rb b/spec/services/imports/lettings_logs_import_service_spec.rb index c74726216..6a9099ef5 100644 --- a/spec/services/imports/lettings_logs_import_service_spec.rb +++ b/spec/services/imports/lettings_logs_import_service_spec.rb @@ -1,7 +1,7 @@ require "rails_helper" RSpec.describe Imports::LettingsLogsImportService do - subject(:lettings_log_service) { described_class.new(storage_service, logger) } + subject(:lettings_log_service) { described_class.new(storage_service, Rails.logger) } let(:storage_service) { instance_double(Storage::S3Service) } let(:logger) { instance_double(ActiveSupport::Logger) } @@ -39,52 +39,69 @@ RSpec.describe Imports::LettingsLogsImportService do allow(FormHandler.instance).to receive(:get_form).with("current_lettings").and_return(real_2022_2023_form) end - context "when importing lettings logs" do - let(:remote_folder) { "lettings_logs" } - 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(:remote_folder) { "lettings_logs" } + 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(: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) } - 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}/#{lettings_log_id4}.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)) - end + 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}/#{lettings_log_id4}.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)) + end - it "successfully create all lettings logs" do + describe "importing lettings logs from S3 asynchronously" do + it "successfully generates background jobs for processing lettings logs" do expect(logger).not_to receive(:error) expect(logger).not_to receive(:warn) - expect(logger).not_to receive(:info) + + assert_enqueued_jobs 4 do + lettings_log_service.create_logs(remote_folder) + end + end + + it "does not immediately change the database" do expect { lettings_log_service.create_logs(remote_folder) } - .to change(LettingsLog, :count).by(4) + .to change(LettingsLog, :count).by(0) end - it "only updates existing lettings logs" do + it "only updates existing lettings logs when import run multiple times" do expect(logger).not_to receive(:error) 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) + + expect do + perform_enqueued_jobs do + lettings_log_service.create_logs(remote_folder) + lettings_log_service.create_logs(remote_folder) + end + end.to change(LettingsLog, :count).by(4) # Rather than 8 end + end + describe "processing background jobs" do context "when there are status discrepancies" do 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) } + let(:logger) { instance_double(ActiveSupport::Logger) } before do allow(storage_service).to receive(:get_file_io) @@ -96,204 +113,26 @@ RSpec.describe Imports::LettingsLogsImportService do end 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 + expect(Rails.logger).to receive(:warn).with(/is not completed/).once + expect(Rails.logger).to receive(:warn).with(/lettings log with old id:#{lettings_log_id5} is incomplete but status should be complete/).once - lettings_log_service.send(:create_log, lettings_log_xml) + perform_enqueued_jobs do + lettings_log_service.send(:enqueue_job, lettings_log_xml) + end end it "on completion the ids of all logs with status discrepancies are logged in a warning" do 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\]/) - - lettings_log_service.create_logs(remote_folder) - end - end - end - - context "when importing a specific log" do - 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 "and the void date is after the start date" do - 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/) - - lettings_log_service.send(:create_log, lettings_log_xml) - lettings_log = LettingsLog.where(old_id: lettings_log_id).first - expect(lettings_log&.voiddate).to be_nil - end - end - - context "and the organisation legacy ID does not exist" do - before { lettings_log_xml.at_xpath("//xmlns:OWNINGORGID").content = 99_999 } - - it "raises an exception" do - expect { lettings_log_service.send(:create_log, lettings_log_xml) } - .to raise_error(RuntimeError, "Organisation not found with legacy ID 99999") - end - end + expect(Rails.logger).to receive(:warn).with(/is not completed/).twice + expect(Rails.logger).to receive(:warn).with(/lettings log with old id:893ufj2s-lq77-42m4-rty6-ej09gh585uy1 is incomplete but status should be complete/).once + expect(Rails.logger).to receive(:warn).with(/lettings log with old id:5ybz29dj-l33t-k1l0-hj86-n4k4ma77xkcd is incomplete but status should be complete/).once - context "and a person is under 16" do - before { lettings_log_xml.at_xpath("//xmlns:P2Age").content = 14 } - - context "when the economic status is set to refuse" do - before { lettings_log_xml.at_xpath("//xmlns:P2Eco").content = "10) Refused" } - - 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 = LettingsLog.where(old_id: lettings_log_id).first - expect(lettings_log&.ecstat2).to be(9) + perform_enqueued_jobs do + lettings_log_service.create_logs(remote_folder) end end - - context "when the relationship to lead tenant is set to refuse" do - before { lettings_log_xml.at_xpath("//xmlns:P2Rel").content = "Refused" } - - 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 - expect(lettings_log&.relat2).to eq("C") - end - end - end - - context "and this is an internal transfer from a non social housing" do - before do - 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 - 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) } - .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 - - 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 - - context "and the net income soft validation is triggered (net_income_value_check)" do - before do - lettings_log_xml.at_xpath("//xmlns:Q8a").content = "1 Weekly" - 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 - - context "and the rent soft validation is triggered (rent_value_check)" do - before do - lettings_log_xml.at_xpath("//xmlns:Q18ai").content = 200.00 - 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 - - context "and the retirement soft validation is triggered (retirement_value_check)" do - before do - lettings_log_xml.at_xpath("//xmlns:P1Age").content = 68 - lettings_log_xml.at_xpath("//xmlns:P1Eco").content = "6) Not Seeking Work" - 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 - - context "and this is a supported housing log with multiple locations under a scheme" do - let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } - - 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 - - context "and this is a supported housing log with a single location under a scheme" do - let(:lettings_log_id) { "0b4a68df-30cc-474a-93c0-a56ce8fdad3b" } - - 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