Stéphane Meny
3 years ago
committed by
GitHub
9 changed files with 187 additions and 45 deletions
@ -0,0 +1,56 @@ |
|||||||
|
class ImportService |
||||||
|
def initialize(storage_service, logger = Rails.logger) |
||||||
|
@storage_service = storage_service |
||||||
|
@logger = logger |
||||||
|
end |
||||||
|
|
||||||
|
def update_organisations(folder) |
||||||
|
filenames = @storage_service.list_files(folder) |
||||||
|
filenames.each do |filename| |
||||||
|
file_io = @storage_service.get_file_io(filename) |
||||||
|
create_organisation(file_io) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def create_organisation(file_io) |
||||||
|
doc = Nokogiri::XML(file_io) |
||||||
|
name = field_value(doc, "name") |
||||||
|
old_visible_id = field_value(doc, "visible-id") |
||||||
|
begin |
||||||
|
Organisation.create!( |
||||||
|
name: name, |
||||||
|
providertype: field_value(doc, "institution-type"), |
||||||
|
phone: field_value(doc, "telephone-number"), |
||||||
|
holds_own_stock: to_boolean(field_value(doc, "holds-stock")), |
||||||
|
active: to_boolean(field_value(doc, "active")), |
||||||
|
old_association_type: field_value(doc, "old-association-type"), |
||||||
|
software_supplier_id: field_value(doc, "software-supplier-id"), |
||||||
|
housing_management_system: field_value(doc, "housing-management-system"), |
||||||
|
choice_based_lettings: to_boolean(field_value(doc, "choice-based-lettings")), |
||||||
|
common_housing_register: to_boolean(field_value(doc, "common-housing-register")), |
||||||
|
choice_allocation_policy: to_boolean(field_value(doc, "choice-allocation-policy")), |
||||||
|
cbl_proportion_percentage: field_value(doc, "cbl-proportion-percentage"), |
||||||
|
enter_affordable_logs: to_boolean(field_value(doc, "enter-affordable-logs")), |
||||||
|
owns_affordable_logs: to_boolean(field_value(doc, "owns-affordable-rent")), |
||||||
|
housing_registration_no: field_value(doc, "housing-registration-no"), |
||||||
|
general_needs_units: field_value(doc, "general-needs-units"), |
||||||
|
supported_housing_units: field_value(doc, "supported-housing-units"), |
||||||
|
unspecified_units: field_value(doc, "unspecified-units"), |
||||||
|
old_org_id: field_value(doc, "id"), |
||||||
|
old_visible_id: old_visible_id, |
||||||
|
) |
||||||
|
rescue ActiveRecord::RecordNotUnique |
||||||
|
@logger.warn("Organisation #{name} is already present with old visible ID #{old_visible_id}, skipping.") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
def field_value(doc, field) |
||||||
|
doc.at_xpath("//institution:#{field}")&.text |
||||||
|
end |
||||||
|
|
||||||
|
def to_boolean(input_string) |
||||||
|
input_string == "true" |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,3 @@ |
|||||||
|
class AddUniqueIndexToOldVisibleId < ActiveRecord::Migration[7.0] |
||||||
|
add_index :organisations, :old_visible_id, unique: true |
||||||
|
end |
@ -0,0 +1,65 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe ImportService do |
||||||
|
let(:storage_service) { instance_double(StorageService) } |
||||||
|
let(:logger) { instance_double(Rails::Rack::Logger) } |
||||||
|
let(:folder_name) { "organisations" } |
||||||
|
let(:filenames) { %w[my_folder/my_file1.xml my_folder/my_file2.xml] } |
||||||
|
let(:fixture_directory) { "spec/fixtures/softwire_imports/organisations" } |
||||||
|
|
||||||
|
def create_organisation_file(fixture_directory, visible_id, name = "my_organisation") |
||||||
|
file = File.open("#{fixture_directory}/7c5bd5fb549c09a2c55d7cb90d7ba84927e64618.xml") |
||||||
|
doc = Nokogiri::XML(file) |
||||||
|
doc.at_xpath("//institution:visible-id").content = visible_id |
||||||
|
doc.at_xpath("//institution:name").content = name |
||||||
|
StringIO.new(doc.to_xml) |
||||||
|
end |
||||||
|
|
||||||
|
context "when importing organisations" do |
||||||
|
subject(:import_service) { described_class.new(storage_service) } |
||||||
|
|
||||||
|
before do |
||||||
|
allow(storage_service).to receive(:list_files) |
||||||
|
.and_return(filenames) |
||||||
|
allow(storage_service).to receive(:get_file_io) |
||||||
|
.with(filenames[0]) |
||||||
|
.and_return(create_organisation_file(fixture_directory, 1)) |
||||||
|
allow(storage_service).to receive(:get_file_io) |
||||||
|
.with(filenames[1]) |
||||||
|
.and_return(create_organisation_file(fixture_directory, 2)) |
||||||
|
end |
||||||
|
|
||||||
|
it "successfully create a new organisation if it does not exist" do |
||||||
|
expect(storage_service).to receive(:list_files).with(folder_name) |
||||||
|
expect(storage_service).to receive(:get_file_io).with(filenames[0]).ordered |
||||||
|
expect(storage_service).to receive(:get_file_io).with(filenames[1]).ordered |
||||||
|
|
||||||
|
expect { import_service.update_organisations(folder_name) }.to change(Organisation, :count).by(2) |
||||||
|
expect(Organisation).to exist(old_visible_id: 1) |
||||||
|
expect(Organisation).to exist(old_visible_id: 2) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when importing organisations twice" do |
||||||
|
subject(:import_service) { described_class.new(storage_service, logger) } |
||||||
|
|
||||||
|
before do |
||||||
|
allow(storage_service).to receive(:list_files).and_return([filenames[0]]) |
||||||
|
allow(storage_service).to receive(:get_file_io).and_return( |
||||||
|
create_organisation_file(fixture_directory, 1), |
||||||
|
create_organisation_file(fixture_directory, 1, "my_new_organisation"), |
||||||
|
) |
||||||
|
end |
||||||
|
|
||||||
|
it "successfully create an organisation the first time, and does not update it" do |
||||||
|
expect(storage_service).to receive(:list_files).with(folder_name).twice |
||||||
|
expect(storage_service).to receive(:get_file_io).with(filenames[0]).twice |
||||||
|
expect(logger).to receive(:warn).once |
||||||
|
|
||||||
|
expect { import_service.update_organisations(folder_name) }.to change(Organisation, :count).by(1) |
||||||
|
expect { import_service.update_organisations(folder_name) }.to change(Organisation, :count).by(0) |
||||||
|
|
||||||
|
expect(Organisation).to exist(old_visible_id: 1, name: "my_organisation") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
Loading…
Reference in new issue