diff --git a/lib/tasks/import_address_from_csv.rake b/lib/tasks/import_address_from_csv.rake new file mode 100644 index 000000000..e910f3a77 --- /dev/null +++ b/lib/tasks/import_address_from_csv.rake @@ -0,0 +1,42 @@ +namespace :data_import do + desc "Import address data from a csv file" + task :import_address_from_csv, %i[file_name] => :environment do |_task, args| + file_name = args[:file_name] + + raise "Usage: rake data_import:import_address_from_csv['csv_file_name']" if file_name.blank? + + s3_service = Storage::S3Service.new(PlatformHelper.is_paas? ? Configuration::PaasConfigurationService.new : Configuration::EnvConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"]) + addresses_csv = CSV.parse(s3_service.get_file_io(file_name), headers: true) + + addresses_csv.each do |row| + lettings_log_id = row[0] + + if lettings_log_id.blank? + Rails.logger.info("Lettings log ID not provided for address: #{[row[1], row[2], row[3], row[4]].join(', ')}") + next + end + + lettings_log = LettingsLog.find_by(id: lettings_log_id) + if lettings_log.blank? + Rails.logger.info("Could not find a lettings log with id #{lettings_log_id}") + next + end + + lettings_log.uprn_known = 0 + lettings_log.uprn = nil + lettings_log.uprn_confirmed = nil + lettings_log.address_line1 = row[1] + lettings_log.address_line2 = row[2] + lettings_log.town_or_city = row[3] + lettings_log.postcode_full = row[4] + lettings_log.postcode_known = lettings_log.postcode_full.present? ? 1 : nil + lettings_log.county = nil + lettings_log.is_la_inferred = nil + lettings_log.la = nil + lettings_log.values_updated_at = Time.zone.now + + lettings_log.save! + Rails.logger.info("Updated lettings log #{lettings_log_id}, with address: #{[lettings_log.address_line1, lettings_log.address_line2, lettings_log.town_or_city, lettings_log.postcode_full].join(', ')}") + end + end +end diff --git a/spec/fixtures/files/addresses_reimport.csv b/spec/fixtures/files/addresses_reimport.csv new file mode 100644 index 000000000..998d2fbfa --- /dev/null +++ b/spec/fixtures/files/addresses_reimport.csv @@ -0,0 +1,6 @@ +lettings_log_id,address_line1,address_line2,town_or_city,postcode_full +{id},address 1,address 2,town,B1 1BB +{id2},address 3,address 4,city,B1 1BB +{id3},,,,C1 1CC +,address 5,address 6,city,D1 1DD +fake_id,address 7,address 8,city,D1 1DD diff --git a/spec/lib/tasks/correct_address_from_csv_spec.rb b/spec/lib/tasks/correct_address_from_csv_spec.rb new file mode 100644 index 000000000..0a3d1c563 --- /dev/null +++ b/spec/lib/tasks/correct_address_from_csv_spec.rb @@ -0,0 +1,154 @@ +require "rails_helper" +require "rake" + +RSpec.describe "data_import" do + def replace_entity_ids(lettings_log, second_lettings_log, third_lettings_log, export_template) + export_template.sub!(/\{id\}/, lettings_log.id.to_s) + export_template.sub!(/\{id2\}/, second_lettings_log.id.to_s) + export_template.sub!(/\{id3\}/, third_lettings_log.id.to_s) + end + + describe ":import_address_from_csv", type: :task do + subject(:task) { Rake::Task["data_import:import_address_from_csv"] } + + let(:instance_name) { "paas_import_instance" } + let(:storage_service) { instance_double(Storage::S3Service) } + let(:env_config_service) { instance_double(Configuration::EnvConfigurationService) } + let(:paas_config_service) { instance_double(Configuration::PaasConfigurationService) } + + before do + allow(Storage::S3Service).to receive(:new).and_return(storage_service) + allow(Configuration::EnvConfigurationService).to receive(:new).and_return(env_config_service) + allow(Configuration::PaasConfigurationService).to receive(:new).and_return(paas_config_service) + allow(ENV).to receive(:[]) + allow(ENV).to receive(:[]).with("IMPORT_PAAS_INSTANCE").and_return(instance_name) + allow(ENV).to receive(:[]).with("VCAP_SERVICES").and_return("dummy") + + Rake.application.rake_require("tasks/import_address_from_csv") + Rake::Task.define_task(:environment) + task.reenable + + WebMock.stub_request(:get, /api.postcodes.io/) + .to_return(status: 200, body: "{\"status\":404,\"error\":\"Postcode not found\"}", headers: {}) + WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/B11BB/) + .to_return(status: 200, body: '{"status":200,"result":{"admin_district":"Westminster","codes":{"admin_district":"E08000035"}}}', headers: {}) + end + + context "when the rake task is run" do + let(:addresses_csv_path) { "addresses_reimport_123.csv" } + let(:wrong_file_path) { "/test/no_csv_here.csv" } + let!(:lettings_log) do + create(:lettings_log, + uprn_known: nil, + uprn: nil, + uprn_confirmed: nil, + address_line1: nil, + address_line2: nil, + town_or_city: nil, + county: nil, + postcode_known: 1, + postcode_full: "A1 1AA", + la: "E06000064", + is_la_inferred: true) + end + + let!(:second_lettings_log) do + create(:lettings_log, + uprn_known: 1, + uprn: "1", + uprn_confirmed: nil, + address_line1: "wrong address line1", + address_line2: "wrong address 2", + town_or_city: "wrong town", + county: "wrong city", + postcode_known: 1, + postcode_full: "A1 1AA", + la: "E06000064", + is_la_inferred: true) + end + + let!(:third_lettings_log) do + create(:lettings_log, + uprn_known: 1, + uprn: "1", + uprn_confirmed: nil, + address_line1: "wrong address line1", + address_line2: "wrong address 2", + town_or_city: "wrong town", + county: "wrong city", + postcode_known: 1, + postcode_full: "A1 1AA", + la: "E06000064", + is_la_inferred: true) + end + + before do + allow(storage_service).to receive(:get_file_io) + .with("addresses_reimport_123.csv") + .and_return(replace_entity_ids(lettings_log, second_lettings_log, third_lettings_log, File.open("./spec/fixtures/files/addresses_reimport.csv").read)) + end + + it "updates the log address when old address was not given" do + task.invoke(addresses_csv_path) + lettings_log.reload + expect(lettings_log.uprn_known).to eq(0) + expect(lettings_log.uprn).to eq(nil) + expect(lettings_log.uprn_confirmed).to eq(nil) + expect(lettings_log.address_line1).to eq("address 1") + expect(lettings_log.address_line2).to eq("address 2") + expect(lettings_log.town_or_city).to eq("town") + expect(lettings_log.county).to eq(nil) + expect(lettings_log.postcode_known).to eq(1) + expect(lettings_log.postcode_full).to eq("B1 1BB") + expect(lettings_log.la).to eq("E08000035") + expect(lettings_log.is_la_inferred).to eq(true) + end + + it "updates the log address when old address was given" do + task.invoke(addresses_csv_path) + second_lettings_log.reload + expect(second_lettings_log.uprn_known).to eq(0) + expect(second_lettings_log.uprn).to eq(nil) + expect(second_lettings_log.uprn_confirmed).to eq(nil) + expect(second_lettings_log.address_line1).to eq("address 3") + expect(second_lettings_log.address_line2).to eq("address 4") + expect(second_lettings_log.town_or_city).to eq("city") + expect(second_lettings_log.county).to eq(nil) + expect(second_lettings_log.postcode_known).to eq(1) + expect(second_lettings_log.postcode_full).to eq("B1 1BB") + expect(second_lettings_log.la).to eq("E08000035") + expect(second_lettings_log.is_la_inferred).to eq(true) + end + + it "updates the log address when new address is not given" do + task.invoke(addresses_csv_path) + third_lettings_log.reload + expect(third_lettings_log.uprn_known).to eq(0) + expect(third_lettings_log.uprn).to eq(nil) + expect(third_lettings_log.uprn_confirmed).to eq(nil) + expect(third_lettings_log.address_line1).to eq(nil) + expect(third_lettings_log.address_line2).to eq(nil) + expect(third_lettings_log.town_or_city).to eq(nil) + expect(third_lettings_log.county).to eq(nil) + expect(third_lettings_log.postcode_known).to eq(1) + expect(third_lettings_log.postcode_full).to eq("C11CC") + expect(third_lettings_log.la).to eq(nil) + expect(third_lettings_log.is_la_inferred).to eq(false) + end + + it "logs the progress of the update" do + expect(Rails.logger).to receive(:info).with("Updated lettings log #{lettings_log.id}, with address: address 1, address 2, town, B1 1BB") + expect(Rails.logger).to receive(:info).with("Updated lettings log #{second_lettings_log.id}, with address: address 3, address 4, city, B1 1BB") + expect(Rails.logger).to receive(:info).with("Updated lettings log #{third_lettings_log.id}, with address: , , , C11CC") + expect(Rails.logger).to receive(:info).with("Lettings log ID not provided for address: address 5, address 6, city, D1 1DD") + expect(Rails.logger).to receive(:info).with("Could not find a lettings log with id fake_id") + + task.invoke(addresses_csv_path) + end + + it "raises an error when no path is given" do + expect { task.invoke(nil) }.to raise_error(RuntimeError, "Usage: rake data_import:import_address_from_csv['csv_file_name']") + end + end + end +end