Browse Source

Location import complete

pull/727/head
Stéphane Meny 3 years ago
parent
commit
eafbabbe30
No known key found for this signature in database
GPG Key ID: 9D0AFEA988527923
  1. 2
      app/controllers/locations_controller.rb
  2. 4
      app/models/location.rb
  3. 8
      app/models/scheme.rb
  4. 168
      app/services/imports/scheme_location_import_service.rb
  5. 2
      app/views/locations/edit.html.erb
  6. 2
      app/views/locations/index.html.erb
  7. 2
      app/views/locations/new.html.erb
  8. 2
      app/views/schemes/check_answers.html.erb
  9. 8
      db/migrate/20220708133052_add_missing_fields_to_location.rb
  10. 6
      db/migrate/20220711081400_rename_units_from_locations.rb
  11. 7
      db/schema.rb
  12. 2
      spec/factories/location.rb
  13. 2
      spec/factories/scheme.rb
  14. 2
      spec/fixtures/imports/scheme_locations/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml
  15. 84
      spec/requests/locations_controller_spec.rb
  16. 10
      spec/services/imports/scheme_import_service_spec.rb
  17. 147
      spec/services/imports/scheme_location_import_service_spec.rb

2
app/controllers/locations_controller.rb

@ -60,7 +60,7 @@ private
end
def location_params
required_params = params.require(:location).permit(:postcode, :name, :total_units, :type_of_unit, :wheelchair_adaptation, :add_another_location).merge(scheme_id: @scheme.id)
required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :wheelchair_adaptation, :add_another_location).merge(scheme_id: @scheme.id)
required_params[:postcode] = required_params[:postcode].delete(" ").upcase.encode("ASCII", "UTF-8", invalid: :replace, undef: :replace, replace: "") if required_params[:postcode]
required_params
end

4
app/models/location.rb

@ -17,8 +17,8 @@ class Location < ApplicationRecord
"Self-contained flat or bedsit with common facilities": 2,
"Shared flat": 3,
"Shared house or hostel": 4,
"Bungalow": 5,
"Self-contained house": 6,
"Bungalow": 6,
"Self-contained house": 7,
}.freeze
enum type_of_unit: TYPE_OF_UNIT

8
app/models/scheme.rb

@ -17,10 +17,10 @@ class Scheme < ApplicationRecord
enum sensitive: SENSITIVE, _suffix: true
REGISTERED_UNDER_CARE_ACT = {
"No": 0,
"Yes – registered care home providing nursing care": 1,
"Yes – registered care home providing personal care": 2,
"Yes – part registered as a care home": 3,
"No": 1,
"Yes – registered care home providing nursing care": 4,
"Yes – registered care home providing personal care": 3,
"Yes – part registered as a care home": 2,
}.freeze
enum registered_under_care_act: REGISTERED_UNDER_CARE_ACT

168
app/services/imports/scheme_location_import_service.rb

@ -4,21 +4,163 @@ module Imports
import_from(folder, :create_scheme_location)
end
def create_scheme_location(xml_document)
management_group = location_field_value(xml_document, "mgmtgroup")
schemes = Scheme.where(old_id: management_group)
raise "Scheme not found with legacy ID #{management_group}" if schemes.empty?
if schemes.size == 1 && schemes.first&.locations&.empty?
scheme = update_scheme(schemes.first, xml_document)
else
scheme = find_scheme_to_merge(schemes, xml_document)
scheme ||= duplicate_scheme(schemes, xml_document)
end
add_location(scheme, xml_document)
end
private
def create_scheme_location(xml_document)
old_visible_id = location_field_value(xml_document, "visible-id")
Scheme.create!(
old_id: location_field_value(xml_document, "id"),
old_visible_id:,
)
rescue ActiveRecord::RecordNotUnique
name = location_field_value(xml_document, "name")
@logger.warn("Location #{name} is already present with old visible ID #{old_visible_id}, skipping.")
end
def location_field_value(xml_document, field)
field_value(xml_document, "scheme", field)
REGISTERED_UNDER_CARE_ACT = {
2 => "(Part-registered care home)",
3 => "(Registered personal care home)",
4 => "(Registered nursing care home)",
}.freeze
def update_scheme(scheme, xml_doc)
attributes = scheme_attributes(xml_doc)
scheme.update!(attributes)
scheme
end
def scheme_attributes(xml_doc)
attributes = {}
attributes["scheme_type"] = safe_string_as_integer(xml_doc, "scheme-type")
registered_under_care_act = safe_string_as_integer(xml_doc, "reg-home-type")
attributes["registered_under_care_act"] = registered_under_care_act.zero? ? nil : registered_under_care_act
attributes["support_type"] = safe_string_as_integer(xml_doc, "support-type")
attributes["intended_stay"] = string_or_nil(xml_doc, "intended-stay")
attributes["primary_client_group"] = string_or_nil(xml_doc, "client-group-1")
attributes["secondary_client_group"] = string_or_nil(xml_doc, "client-group-2")
attributes["secondary_client_group"] = nil if attributes["primary_client_group"] == attributes["secondary_client_group"]
attributes["sensitive"] = sensitive(xml_doc)
attributes["end_date"] = parse_end_date(xml_doc)
attributes
end
def add_location(scheme, xml_doc)
end_date = parse_end_date(xml_doc)
old_id = string_or_nil(xml_doc, "id")
if end_date.nil? || end_date >= Time.zone.now
# wheelchair_adaptation: string_or_nil(xml_doc, "mobility-type"),
begin
Location.create!(
postcode: string_or_nil(xml_doc, "postcode"),
units: safe_string_as_integer(xml_doc, "total-units"),
type_of_unit: safe_string_as_integer(xml_doc, "unit-type"),
old_visible_id: safe_string_as_integer(xml_doc, "visible-id"),
old_id:,
scheme:,
)
rescue ActiveRecord::RecordNotUnique
@logger.warn("Location is already present with legacy ID #{old_id}, skipping")
end
else
@logger.warn("Location with legacy ID #{old_id} is expired (#{end_date}), skipping")
end
end
def find_scheme_to_merge(schemes, xml_doc)
attributes = scheme_attributes(xml_doc)
schemes.each do |scheme|
if scheme.scheme_type_before_type_cast == attributes["scheme_type"] &&
scheme.registered_under_care_act_before_type_cast == attributes["registered_under_care_act"] &&
scheme.support_type_before_type_cast == attributes["support_type"] &&
scheme.intended_stay_before_type_cast == attributes["intended_stay"] &&
scheme.primary_client_group_before_type_cast == attributes["primary_client_group"] &&
scheme.secondary_client_group_before_type_cast == attributes["secondary_client_group"]
return scheme
end
end
nil
end
def duplicate_scheme(schemes, xml_doc)
# Since all schemes in the array are different, pick the first one
# In the future, consider a better selection method if needed
old_scheme = schemes.first
new_scheme = old_scheme.dup
update_scheme(new_scheme, xml_doc)
if old_scheme.scheme_type != new_scheme.scheme_type
rename_schemes(old_scheme, new_scheme, :scheme_type)
elsif old_scheme.registered_under_care_act != new_scheme.registered_under_care_act
rename_registered_care(old_scheme, new_scheme)
elsif old_scheme.support_type != new_scheme.support_type
rename_schemes(old_scheme, new_scheme, :support_type)
elsif old_scheme.intended_stay != new_scheme.intended_stay
rename_schemes(old_scheme, new_scheme, :intended_stay)
elsif old_scheme.primary_client_group != new_scheme.primary_client_group
rename_schemes(old_scheme, new_scheme, :primary_client_group)
elsif old_scheme.secondary_client_group != new_scheme.secondary_client_group
rename_schemes(old_scheme, new_scheme, :secondary_client_group)
end
new_scheme
end
def rename_registered_care(*schemes)
schemes.each do |scheme|
if REGISTERED_UNDER_CARE_ACT.key?(scheme.registered_under_care_act_before_type_cast)
suffix = REGISTERED_UNDER_CARE_ACT[scheme.registered_under_care_act_before_type_cast]
scheme.update!(service_name: "#{scheme.service_name} - #{suffix}")
end
end
end
def rename_schemes(old_scheme, new_scheme, attribute)
old_scheme_attribute = old_scheme.send(attribute)
new_scheme_attribute = new_scheme.send(attribute)
if old_scheme_attribute
old_scheme_name = "#{old_scheme.service_name} - #{old_scheme_attribute}"
old_scheme.update!(service_name: old_scheme_name)
end
if new_scheme_attribute
new_scheme_name = "#{new_scheme.service_name} - #{new_scheme_attribute}"
new_scheme.update!(service_name: new_scheme_name)
end
end
def location_field_value(xml_doc, field)
field_value(xml_doc, "scheme", field)
end
def string_or_nil(xml_doc, attribute)
str = location_field_value(xml_doc, attribute)
str.presence
end
# Safe: A string that represents only an integer (or empty/nil)
def safe_string_as_integer(xml_doc, attribute)
str = location_field_value(xml_doc, attribute)
Integer(str, exception: false)
end
def sensitive(xml_doc)
value = string_or_nil(xml_doc, "sensitive")
if value == "true"
1
else
0
end
end
def parse_end_date(xml_doc)
end_date = string_or_nil(xml_doc, "end-date")
Time.zone.parse(end_date) if end_date
end
end
end

2
app/views/locations/edit.html.erb

@ -23,7 +23,7 @@
label: { text: "Name (optional)", size: "m" },
hint: { text: "This is how you refer to this location within your organisation" } %>
<%= f.govuk_number_field :total_units,
<%= f.govuk_number_field :units,
label: { text: "Total number of units at this location", size: "m" },
width: 2,
hint: { text: "A unit can be a bedroom in a shared house or flat, or a house with 4 bedrooms. Do not include bedrooms used for wardens, managers, volunteers or sleep-in staff.s" },

2
app/views/locations/index.html.erb

@ -37,7 +37,7 @@
<%= body.row do |row| %>
<% row.cell(text: location.id) %>
<% row.cell(text: location.postcode) %>
<% row.cell(text: location.total_units) %>
<% row.cell(text: location.units) %>
<% row.cell(text: simple_format("<span>#{location.type_of_unit}</span>#{location.wheelchair_adaptation == 'Yes' ? "\n<span class=\"govuk-!-font-weight-regular app-!-colour-muted\">With wheelchair adaptations</span>" : ''}")) %>
<% end %>
<% end %>

2
app/views/locations/new.html.erb

@ -23,7 +23,7 @@
label: { text: "Name (optional)", size: "m" },
hint: { text: "This is how you refer to this location within your organisation" } %>
<%= f.govuk_number_field :total_units,
<%= f.govuk_number_field :units,
label: { text: "Total number of units at this location", size: "m" },
width: 2,
hint: { text: "A unit can be a bedroom in a shared house or flat, or a house with 4 bedrooms. Do not include bedrooms used for wardens, managers, volunteers or sleep-in staff.s" },

2
app/views/schemes/check_answers.html.erb

@ -90,7 +90,7 @@
<%= body.row do |row| %>
<% row.cell(text: location.id) %>
<% row.cell(text: simple_format(location_cell(location), { class: "govuk-!-font-weight-bold" }, wrapper_tag: "div")) %>
<% row.cell(text: location.total_units) %>
<% row.cell(text: location.units) %>
<% row.cell(text: simple_format("<span>#{location.type_of_unit}</span>#{location.wheelchair_adaptation == 'Yes' ? "\n<span class=\"govuk-!-font-weight-regular app-!-colour-muted\">With wheelchair adaptations</span>" : ''}")) %>
<% end %>
<% end %>

8
db/migrate/20220708133052_add_missing_fields_to_location.rb

@ -0,0 +1,8 @@
class AddMissingFieldsToLocation < ActiveRecord::Migration[7.0]
def change
change_table :locations, bulk: true do |t|
t.column :old_id, :string
t.column :old_visible_id, :integer
end
end
end

6
db/migrate/20220711081400_rename_units_from_locations.rb

@ -0,0 +1,6 @@
class RenameUnitsFromLocations < ActiveRecord::Migration[7.0]
def change
rename_column :locations, :total_units, :units
add_column :schemes, :total_units, :integer
end
end

7
db/schema.rb

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_07_08_112603) do
ActiveRecord::Schema[7.0].define(version: 2022_07_11_081400) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -246,8 +246,10 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_08_112603) do
t.string "county"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "total_units"
t.integer "units"
t.integer "type_of_unit"
t.string "old_id"
t.integer "old_visible_id"
t.index ["scheme_id"], name: "index_locations_on_scheme_id"
end
@ -316,6 +318,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_08_112603) do
t.string "arrangement_type"
t.string "old_id"
t.integer "old_visible_id"
t.integer "total_units"
t.index ["managing_organisation_id"], name: "index_schemes_on_managing_organisation_id"
t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id"
end

2
spec/factories/location.rb

@ -3,7 +3,7 @@ FactoryBot.define do
location_code { Faker::Name.initials(number: 10) }
postcode { Faker::Address.postcode.delete(" ") }
name { Faker::Address.street_name }
type_of_unit { Faker::Number.within(range: 1..6) }
type_of_unit { [1, 2, 3, 4, 6, 7].sample }
type_of_building { Faker::Lorem.word }
wheelchair_adaptation { 0 }
county { Faker::Address.state }

2
spec/factories/scheme.rb

@ -2,7 +2,7 @@ FactoryBot.define do
factory :scheme do
service_name { Faker::Name.name }
sensitive { Faker::Number.within(range: 0..1) }
registered_under_care_act { Faker::Number.within(range: 0..1) }
registered_under_care_act { 1 }
support_type { Faker::Number.within(range: 0..6) }
scheme_type { 0 }
intended_stay { %w[M P S V X].sample }

2
spec/fixtures/imports/scheme_locations/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml vendored

@ -9,7 +9,7 @@
<scheme:scheme-type>7</scheme:scheme-type>
<scheme:unit-type>6</scheme:unit-type>
<scheme:reg-home-type>1</scheme:reg-home-type>
<scheme:support-type>0</scheme:support-type>
<scheme:support-type>2</scheme:support-type>
<scheme:mobility-type>W</scheme:mobility-type>
<scheme:sp-grant>False</scheme:sp-grant>
<scheme:intended-stay>P</scheme:intended-stay>

84
spec/requests/locations_controller_spec.rb

@ -90,7 +90,7 @@ RSpec.describe LocationsController, type: :request do
context "when signed in as a data coordinator" do
let(:user) { FactoryBot.create(:user, :data_coordinator) }
let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) }
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
before do
sign_in user
@ -108,13 +108,13 @@ RSpec.describe LocationsController, type: :request do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.postcode).to eq("ZZ11ZZ")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
context "when postcode is submitted with lower case" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
it "creates a new location for scheme with postcode " do
expect(Location.last.postcode).to eq("ZZ11ZZ")
@ -123,7 +123,7 @@ RSpec.describe LocationsController, type: :request do
context "when trying to add location to a scheme that belongs to another organisation" do
let(:another_scheme) { FactoryBot.create(:scheme) }
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
it "displays the new page with an error message" do
post "/schemes/#{another_scheme.id}/locations", params: params
@ -132,7 +132,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when required postcode param is missing" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@ -141,7 +141,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when do you want to add another location is selected as yes" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
it "creates a new location for scheme with valid params and redirects to correct page" do
expect { post "/schemes/#{scheme.id}/locations", params: }.to change(Location, :count).by(1)
@ -153,14 +153,14 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is selected as no" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
it "creates a new location for scheme with valid params and redirects to correct page" do
expect { post "/schemes/#{scheme.id}/locations", params: }.to change(Location, :count).by(1)
@ -172,14 +172,14 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is not selected" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
it "creates a new location for scheme with valid params and redirects to correct page" do
expect { post "/schemes/#{scheme.id}/locations", params: }.to change(Location, :count).by(1)
@ -191,7 +191,7 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
@ -201,7 +201,7 @@ RSpec.describe LocationsController, type: :request do
context "when signed in as a support user" do
let(:user) { FactoryBot.create(:user, :support) }
let!(:scheme) { FactoryBot.create(:scheme) }
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
@ -219,13 +219,13 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.postcode).to eq("ZZ11ZZ")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
context "when postcode is submitted with lower case" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
it "creates a new location for scheme with postcode " do
expect(Location.last.postcode).to eq("ZZ11ZZ")
@ -233,7 +233,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when required postcode param is missing" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No" } } }
it "displays the new page with an error message" do
post "/schemes/#{scheme.id}/locations", params: params
@ -243,7 +243,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when do you want to add another location is selected as yes" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
it "creates a new location for scheme with valid params and redirects to correct page" do
expect { post "/schemes/#{scheme.id}/locations", params: }.to change(Location, :count).by(1)
@ -254,14 +254,14 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is selected as no" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
it "creates a new location for scheme with valid params and redirects to correct page" do
expect { post "/schemes/#{scheme.id}/locations", params: }.to change(Location, :count).by(1)
@ -272,14 +272,14 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is not selected" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
it "creates a new location for scheme with valid params and redirects to correct page" do
expect { post "/schemes/#{scheme.id}/locations", params: }.to change(Location, :count).by(1)
@ -290,7 +290,7 @@ RSpec.describe LocationsController, type: :request do
it "creates a new location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
@ -390,7 +390,7 @@ RSpec.describe LocationsController, type: :request do
let(:user) { FactoryBot.create(:user, :data_coordinator) }
let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) }
let!(:location) { FactoryBot.create(:location, scheme:) }
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
before do
sign_in user
@ -407,13 +407,13 @@ RSpec.describe LocationsController, type: :request do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.postcode).to eq("ZZ11ZZ")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
context "when postcode is submitted with lower case" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
it "updates existing location for scheme with postcode " do
expect(Location.last.postcode).to eq("ZZ11ZZ")
@ -423,7 +423,7 @@ RSpec.describe LocationsController, type: :request do
context "when trying to update location for a scheme that belongs to another organisation" do
let(:another_scheme) { FactoryBot.create(:scheme) }
let(:another_location) { FactoryBot.create(:location) }
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
it "displays the new page with an error message" do
patch "/schemes/#{another_scheme.id}/locations/#{another_location.id}", params: params
@ -432,7 +432,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when required postcode param is invalid" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "invalid" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "invalid" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@ -441,7 +441,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when do you want to add another location is selected as yes" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
it "updates existing location for scheme with valid params and redirects to correct page" do
follow_redirect!
@ -452,14 +452,14 @@ RSpec.describe LocationsController, type: :request do
it "updates existing location for scheme with valid params" do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is selected as no" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
it "updates existing location for scheme with valid params and redirects to correct page" do
follow_redirect!
@ -470,14 +470,14 @@ RSpec.describe LocationsController, type: :request do
it "updates existing location for scheme with valid params" do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is not selected" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
it "updates existing location for scheme with valid params and redirects to correct page" do
follow_redirect!
@ -488,7 +488,7 @@ RSpec.describe LocationsController, type: :request do
it "updates existing location for scheme with valid params" do
expect(Location.last.scheme.owning_organisation_id).to eq(user.organisation_id)
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
@ -499,7 +499,7 @@ RSpec.describe LocationsController, type: :request do
let(:user) { FactoryBot.create(:user, :data_coordinator) }
let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) }
let!(:location) { FactoryBot.create(:location, scheme:) }
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
@ -516,13 +516,13 @@ RSpec.describe LocationsController, type: :request do
it "updates existing location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.postcode).to eq("ZZ11ZZ")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
context "when postcode is submitted with lower case" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "zz1 1zz" } } }
it "updates a location for scheme with postcode " do
expect(Location.last.postcode).to eq("ZZ11ZZ")
@ -530,7 +530,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when required postcode param is missing" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "invalid" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "invalid" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
@ -539,7 +539,7 @@ RSpec.describe LocationsController, type: :request do
end
context "when do you want to add another location is selected as yes" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "Yes", postcode: "ZZ1 1ZZ" } } }
it "updates location for scheme with valid params and redirects to correct page" do
follow_redirect!
@ -549,14 +549,14 @@ RSpec.describe LocationsController, type: :request do
it "updates existing location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is selected as no" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", add_another_location: "No", postcode: "ZZ1 1ZZ" } } }
it "updates a location for scheme with valid params and redirects to correct page" do
follow_redirect!
@ -566,14 +566,14 @@ RSpec.describe LocationsController, type: :request do
it "updates existing location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end
end
context "when do you want to add another location is not selected" do
let(:params) { { location: { name: "Test", total_units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
let(:params) { { location: { name: "Test", units: "5", type_of_unit: "Bungalow", wheelchair_adaptation: "No", postcode: "ZZ1 1ZZ" } } }
it "updates a location for scheme with valid params and redirects to correct page" do
follow_redirect!
@ -583,7 +583,7 @@ RSpec.describe LocationsController, type: :request do
it "updates a location for scheme with valid params" do
expect(Location.last.name).to eq("Test")
expect(Location.last.total_units).to eq(5)
expect(Location.last.units).to eq(5)
expect(Location.last.type_of_unit).to eq("Bungalow")
expect(Location.last.wheelchair_adaptation).to eq("No")
end

10
spec/services/imports/scheme_import_service_spec.rb

@ -16,7 +16,7 @@ RSpec.describe Imports::SchemeImportService do
File.open("#{directory}/#{filename}.xml")
end
context "when importing case logs" do
context "when importing schemes" do
let(:remote_folder) { "mgmtgroups" }
before do
@ -25,10 +25,10 @@ RSpec.describe Imports::SchemeImportService do
.and_return(%W[#{remote_folder}/#{scheme_id}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{scheme_id}.xml")
.and_return(open_file(fixture_directory, scheme_id), open_file(fixture_directory, scheme_id))
.and_return(open_file(fixture_directory, scheme_id))
end
it "successfully create all case logs" do
it "successfully create all schemes" do
expect(logger).not_to receive(:error)
expect(logger).not_to receive(:warn)
expect(logger).not_to receive(:info)
@ -55,8 +55,8 @@ RSpec.describe Imports::SchemeImportService do
before { scheme_xml.at_xpath("//mgmtgroup:status").content = "Temporary" }
it "does not create the scheme" do
scheme = scheme_service.create_scheme(scheme_xml)
expect(scheme).to be_nil
expect { scheme_service.create_scheme(scheme_xml) }
.not_to change(Scheme, :count)
end
end
end

147
spec/services/imports/scheme_location_import_service_spec.rb

@ -0,0 +1,147 @@
require "rails_helper"
RSpec.describe Imports::SchemeLocationImportService do
subject(:location_service) { described_class.new(storage_service, logger) }
let(:storage_service) { instance_double(StorageService) }
let(:logger) { instance_double(ActiveSupport::Logger) }
let(:fixture_directory) { "spec/fixtures/imports/scheme_locations" }
let(:first_location_id) { "0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e" }
let(:second_location_id) { "0bb3836b70b4dd9903263d5a764a5c45b964a89d" }
let!(:scheme) { FactoryBot.create(:scheme, service_name: "Management Group", old_id: "6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d") }
def open_file(directory, filename)
File.open("#{directory}/#{filename}.xml")
end
context "when importing scheme locations" do
let(:remote_folder) { "schemes" }
before do
# Stub the S3 file listing and download
allow(storage_service).to receive(:list_files)
.and_return(%W[#{remote_folder}/#{first_location_id}.xml #{remote_folder}/#{second_location_id}.xml])
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{first_location_id}.xml")
.and_return(open_file(fixture_directory, first_location_id))
allow(storage_service).to receive(:get_file_io)
.with("#{remote_folder}/#{second_location_id}.xml")
.and_return(open_file(fixture_directory, second_location_id))
end
it "successfully create all scheme locations" do
expect(logger).not_to receive(:error)
expect(logger).not_to receive(:warn)
expect(logger).not_to receive(:info)
expect { location_service.create_scheme_locations(remote_folder) }
.to change(Location, :count).by(2)
.and(change(Scheme, :count).by(0))
end
end
context "when importing different scheme locations" do
let(:location_xml_1) { Nokogiri::XML(open_file(fixture_directory, first_location_id)) }
let(:location_xml_2) { Nokogiri::XML(open_file(fixture_directory, second_location_id)) }
before { location_service.create_scheme_location(location_xml_1) }
context "and the scheme type is different" do
before { location_xml_2.at_xpath("//scheme:scheme-type").content = "5" }
it "renames the location scheme name" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Housing for older people")
expect(new_scheme.service_name).to eq("Management Group - Direct Access Hostel")
end
end
context "and the registered under care act is different" do
before { location_xml_2.at_xpath("//scheme:reg-home-type").content = "2" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group")
expect(new_scheme.service_name).to eq("Management Group - (Part-registered care home)")
end
end
context "and the support type is different" do
before { location_xml_2.at_xpath("//scheme:support-type").content = "3" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Low levels of support")
expect(new_scheme.service_name).to eq("Management Group - Medium levels of support")
end
end
context "and the intended stay is different" do
before { location_xml_2.at_xpath("//scheme:intended-stay").content = "S" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Permanent")
expect(new_scheme.service_name).to eq("Management Group - Short stay")
end
end
context "and the primary client group is different" do
before { location_xml_2.at_xpath("//scheme:client-group-1").content = "F" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group - Older people with support needs")
expect(new_scheme.service_name).to eq("Management Group - People with drug problems")
end
end
context "and the secondary client group is different" do
before { location_xml_2.at_xpath("//scheme:client-group-2").content = "S" }
it "renames both scheme names" do
location = location_service.create_scheme_location(location_xml_2)
old_scheme = Scheme.find(scheme.id)
new_scheme = location.scheme
expect(old_scheme.service_name).to eq("Management Group")
expect(new_scheme.service_name).to eq("Management Group - Rough sleepers")
end
end
end
context "when importing a specific scheme location" do
let(:location_xml) { Nokogiri::XML(open_file(fixture_directory, first_location_id)) }
context "and the end date is before the current date" do
before do
Timecop.freeze(2022, 6, 1)
location_xml.at_xpath("//scheme:end-date").content = "2022-05-01"
end
after { Timecop.unfreeze }
it "does not create the location" do
expect(logger).to receive(:warn).with("Location with legacy ID 0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e is expired (2022-05-01 00:00:00 +0100), skipping")
expect { location_service.create_scheme_location(location_xml) }
.not_to change(Location, :count)
end
end
end
end
Loading…
Cancel
Save