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