Browse Source

Rake task to fix empty tenant code (#622)

* Rake task to fix empty tenant code

* Rewrite test for clarity

* Refactor call to update
pull/626/head v0.1.12
Stéphane Meny 3 years ago committed by GitHub
parent
commit
c9702d1f32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 35
      app/services/imports/case_logs_field_import_service.rb
  2. 18
      lib/tasks/data_import_field.rake
  3. 9
      spec/lib/tasks/data_import_spec.rb
  4. 57
      spec/lib/tasks/date_import_field_spec.rb
  5. 76
      spec/services/imports/case_logs_field_import_service_spec.rb

35
app/services/imports/case_logs_field_import_service.rb

@ -0,0 +1,35 @@
module Imports
class CaseLogsFieldImportService < ImportService
def update_field(field, folder)
case field
when "tenant_code"
import_from(folder, :update_tenant_code)
else
raise "Updating #{field} is not supported by the field import service"
end
end
private
def update_tenant_code(xml_doc)
old_id = field_value(xml_doc, "meta", "document-id")
record = CaseLog.find_by(old_id:)
if record.present?
tenant_code = string_or_nil(xml_doc, "_2bTenCode")
if tenant_code.present? && record.tenant_code.blank?
record.update!(tenant_code:)
else
@logger.info("Case Log #{record.id} has a value for tenant_code, skipping update")
end
else
@logger.warn("Could not find record matching legacy ID #{old_id}")
end
end
def string_or_nil(xml_doc, attribute)
str = field_value(xml_doc, "xmlns", attribute)
str.presence
end
end
end

18
lib/tasks/data_import_field.rake

@ -0,0 +1,18 @@
namespace :core do
desc "Update database field from data XMLs provided by Softwire"
task :data_import_field, %i[field path] => :environment do |_task, args|
field = args[:field]
path = args[:path]
raise "Usage: rake core:data_import_field['field','path/to/xml_files']" if path.blank? || field.blank?
storage_service = StorageService.new(PaasConfigurationService.new, ENV["IMPORT_PAAS_INSTANCE"])
# We only allow a reduced list of known fields to be updatable
case field
when "tenant_code"
Imports::CaseLogsFieldImportService.new(storage_service).update_field(field, path)
else
raise "Field #{field} cannot be updated by data_import_field"
end
end
end

9
spec/lib/tasks/data_import_spec.rb

@ -4,13 +4,9 @@ require "rake"
describe "rake core:data_import", type: :task do describe "rake core:data_import", type: :task do
subject(:task) { Rake::Task["core:data_import"] } subject(:task) { Rake::Task["core:data_import"] }
let(:fixture_path) { "spec/fixtures/softwire_imports/organisations" }
let(:instance_name) { "paas_import_instance" } let(:instance_name) { "paas_import_instance" }
let(:type) { "organisation" }
let(:storage_service) { instance_double(StorageService) } let(:storage_service) { instance_double(StorageService) }
let(:paas_config_service) { instance_double(PaasConfigurationService) } let(:paas_config_service) { instance_double(PaasConfigurationService) }
let(:import_service) { instance_double(Imports::OrganisationImportService) }
before do before do
Rake.application.rake_require("tasks/data_import") Rake.application.rake_require("tasks/data_import")
@ -24,6 +20,10 @@ describe "rake core:data_import", type: :task do
end end
context "when importing organisation data" do context "when importing organisation data" do
let(:type) { "organisation" }
let(:import_service) { instance_double(Imports::OrganisationImportService) }
let(:fixture_path) { "spec/fixtures/softwire_imports/organisations" }
before do before do
allow(Imports::OrganisationImportService).to receive(:new).and_return(import_service) allow(Imports::OrganisationImportService).to receive(:new).and_return(import_service)
end end
@ -40,6 +40,7 @@ describe "rake core:data_import", type: :task do
context "when importing user data" do context "when importing user data" do
let(:type) { "user" } let(:type) { "user" }
let(:import_service) { instance_double(Imports::UserImportService) } let(:import_service) { instance_double(Imports::UserImportService) }
let(:fixture_path) { "spec/fixtures/softwire_imports/users" }
before do before do
allow(Imports::UserImportService).to receive(:new).and_return(import_service) allow(Imports::UserImportService).to receive(:new).and_return(import_service)

57
spec/lib/tasks/date_import_field_spec.rb

@ -0,0 +1,57 @@
require "rails_helper"
require "rake"
describe "rake core:data_import_field", type: :task do
subject(:task) { Rake::Task["core:data_import_field"] }
let(:instance_name) { "paas_import_instance" }
let(:storage_service) { instance_double(StorageService) }
let(:paas_config_service) { instance_double(PaasConfigurationService) }
before do
Rake.application.rake_require("tasks/data_import_field")
Rake::Task.define_task(:environment)
task.reenable
allow(StorageService).to receive(:new).and_return(storage_service)
allow(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)
end
context "when importing a case log field" do
let(:import_service) { instance_double(Imports::CaseLogsFieldImportService) }
let(:fixture_path) { "spec/fixtures/softwire_imports/case_logs" }
before do
allow(Imports::CaseLogsFieldImportService).to receive(:new).and_return(import_service)
allow(import_service).to receive(:update_field)
end
context "and we update the tenant_code field" do
let(:field) { "tenant_code" }
it "properly configures the storage service" do
expect(StorageService).to receive(:new).with(paas_config_service, instance_name)
task.invoke(field, fixture_path)
end
it "calls the expected update method with parameters" do
expect(import_service).to receive(:update_field).with(field, fixture_path)
task.invoke(field, fixture_path)
end
end
it "raises an exception if no parameters are provided" do
expect { task.invoke }.to raise_error(/Usage/)
end
it "raises an exception if a single parameter is provided" do
expect { task.invoke("one_parameter") }.to raise_error(/Usage/)
end
it "raises an exception if the field is not supported" do
expect { task.invoke("random_field", "my_path") }.to raise_error("Field random_field cannot be updated by data_import_field")
end
end
end

76
spec/services/imports/case_logs_field_import_service_spec.rb

@ -0,0 +1,76 @@
require "rails_helper"
RSpec.describe Imports::CaseLogsFieldImportService do
subject(:import_service) { described_class.new(storage_service, logger) }
let(:storage_service) { instance_double(StorageService) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json", "2021_2022") }
let(:fixture_directory) { "spec/fixtures/softwire_imports/case_logs" }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
end
before do
# Owning and Managing organisations
FactoryBot.create(:organisation, old_visible_id: "1", provider_type: "PRP")
# Created by users
FactoryBot.create(:user, old_user_id: "c3061a2e6ea0b702e6f6210d5c52d2a92612d2aa")
# Stub the form handler to use the real form
allow(FormHandler.instance).to receive(:get_form).with("2021_2022").and_return(real_2021_2022_form)
WebMock.stub_request(:get, /api.postcodes.io\/postcodes\/LS166FT/)
.to_return(status: 200, body: '{"status":200,"result":{"codes":{"admin_district":"E08000035"}}}', headers: {})
end
context "when updating a specific log value" do
let(:case_log_id) { "0ead17cb-1668-442d-898c-0d52879ff592" }
let(:case_log_file) { open_file(fixture_directory, case_log_id) }
let(:case_log_xml) { Nokogiri::XML(case_log_file) }
let(:remote_folder) { "case_logs" }
let(:field) { "tenant_code" }
before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
.and_return(["#{remote_folder}/#{case_log_id}.xml"])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{case_log_id}.xml")
.and_return(case_log_file)
end
context "and the case log was previously imported" do
let(:case_log) { CaseLog.find_by(old_id: case_log_id) }
before do
Imports::CaseLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
case_log_file.rewind
end
it "logs that the tenant_code already has a value and does not update the case_log" do
expect(logger).to receive(:info).with(/Case Log \d+ has a value for tenant_code, skipping update/)
expect { import_service.send(:update_field, field, remote_folder) }
.not_to(change { case_log.reload.tenant_code })
end
end
context "and the case log was previously imported with empty fields" do
let(:case_log) { CaseLog.find_by(old_id: case_log_id) }
before do
Imports::CaseLogsImportService.new(storage_service, logger).create_logs(fixture_directory)
case_log_file.rewind
case_log.update!(tenant_code: nil)
end
it "updates the case_log" do
expect { import_service.send(:update_field, field, remote_folder) }
.to(change { case_log.reload.tenant_code })
end
end
end
end
Loading…
Cancel
Save