Browse Source

Merge branch 'main' into CLDC-3089-use-rails-routing-everywhere

pull/2348/head
natdeanlewissoftwire 2 years ago
parent
commit
7e0ba76a0e
  1. 9
      app/controllers/locations_controller.rb
  2. 2
      app/controllers/organisations_controller.rb
  3. 11
      app/controllers/schemes_controller.rb
  4. 4
      app/helpers/locations_helper.rb
  5. 4
      app/helpers/schemes_helper.rb
  6. 4
      app/models/form/lettings/questions/location_id.rb
  7. 7
      app/models/form/lettings/questions/nationality_all.rb
  8. 10
      app/models/form/lettings/questions/scheme_id.rb
  9. 7
      app/models/form/sales/questions/nationality_all.rb
  10. 7
      app/models/location.rb
  11. 10
      app/models/scheme.rb
  12. 17
      app/policies/location_policy.rb
  13. 17
      app/policies/scheme_policy.rb
  14. 8
      app/services/feature_toggle.rb
  15. 3
      app/views/locations/check_answers.html.erb
  16. 24
      app/views/locations/delete_confirmation.html.erb
  17. 11
      app/views/locations/show.html.erb
  18. 4
      app/views/schemes/check_answers.html.erb
  19. 24
      app/views/schemes/delete_confirmation.html.erb
  20. 7
      app/views/schemes/show.html.erb
  21. 2
      config/locales/en.yml
  22. 4
      config/routes.rb
  23. 5
      db/migrate/20240301125651_add_discarded_at_column.rb
  24. 5
      db/migrate/20240304100017_add_discarded_at_column_to_schemes.rb
  25. 2
      db/schema.rb
  26. 2
      spec/fixtures/files/lettings_log_csv_export_labels_23_during_24_period.csv
  27. 2
      spec/fixtures/files/lettings_log_csv_export_labels_24.csv
  28. 2
      spec/fixtures/files/sales_logs_csv_export_labels_23_during_24_period.csv
  29. 2
      spec/fixtures/files/sales_logs_csv_export_labels_24.csv
  30. 12
      spec/models/form/lettings/questions/location_id_spec.rb
  31. 13
      spec/models/form/lettings/questions/scheme_id_spec.rb
  32. 8
      spec/models/scheme_spec.rb
  33. 92
      spec/policies/location_policy_spec.rb
  34. 94
      spec/policies/scheme_policy_spec.rb
  35. 270
      spec/requests/locations_controller_spec.rb
  36. 5
      spec/requests/organisations_controller_spec.rb
  37. 286
      spec/requests/schemes_controller_spec.rb
  38. 35
      spec/services/csv/lettings_log_csv_service_spec.rb
  39. 35
      spec/services/csv/sales_log_csv_service_spec.rb
  40. 2
      spec/views/locations/show.html.erb_spec.rb

9
app/controllers/locations_controller.rb

@ -14,8 +14,8 @@ class LocationsController < ApplicationController
def index def index
authorize @scheme authorize @scheme
@pagy, @locations = pagy(filter_manager.filtered_locations(@scheme.locations, search_term, session_filters)) @pagy, @locations = pagy(filter_manager.filtered_locations(@scheme.locations.visible, search_term, session_filters))
@total_count = @scheme.locations.size @total_count = @scheme.locations.visible.size
@searched = search_term.presence @searched = search_term.presence
@filter_type = "scheme_locations" @filter_type = "scheme_locations"
end end
@ -230,6 +230,11 @@ class LocationsController < ApplicationController
end end
end end
def delete
@location.discard!
redirect_to scheme_locations_path(@scheme), notice: I18n.t("notification.location_deleted", postcode: @location.postcode)
end
private private
def authorize_user def authorize_user

2
app/controllers/organisations_controller.rb

@ -21,7 +21,7 @@ class OrganisationsController < ApplicationController
end end
def schemes def schemes
organisation_schemes = Scheme.where(owning_organisation: [@organisation] + @organisation.parent_organisations) organisation_schemes = Scheme.visible.where(owning_organisation: [@organisation] + @organisation.parent_organisations)
@pagy, @schemes = pagy(filter_manager.filtered_schemes(organisation_schemes, search_term, session_filters)) @pagy, @schemes = pagy(filter_manager.filtered_schemes(organisation_schemes, search_term, session_filters))
@searched = search_term.presence @searched = search_term.presence

11
app/controllers/schemes_controller.rb

@ -13,11 +13,11 @@ class SchemesController < ApplicationController
def index def index
redirect_to schemes_organisation_path(current_user.organisation) unless current_user.support? redirect_to schemes_organisation_path(current_user.organisation) unless current_user.support?
all_schemes = Scheme.all all_visible_schemes = Scheme.visible
@pagy, @schemes = pagy(filter_manager.filtered_schemes(all_schemes, search_term, session_filters)) @pagy, @schemes = pagy(filter_manager.filtered_schemes(all_visible_schemes, search_term, session_filters))
@searched = search_term.presence @searched = search_term.presence
@total_count = all_schemes.size @total_count = all_visible_schemes.size
@filter_type = "schemes" @filter_type = "schemes"
end end
@ -223,6 +223,11 @@ class SchemesController < ApplicationController
def csv_confirmation; end def csv_confirmation; end
def delete
@scheme.discard!
redirect_to schemes_organisation_path(@scheme.owning_organisation), notice: I18n.t("notification.scheme_deleted", service_name: @scheme.service_name)
end
private private
def authorize_user def authorize_user

4
app/helpers/locations_helper.rb

@ -73,6 +73,10 @@ module LocationsHelper
return govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated? return govuk_button_link_to "Reactivate this location", scheme_location_new_reactivation_path(location.scheme, location) if location.deactivated?
end end
def delete_location_link(location)
govuk_button_link_to "Delete this location", scheme_location_delete_confirmation_path(location.scheme, location), warning: true
end
def location_creation_success_notice(location) def location_creation_success_notice(location)
if location.confirmed if location.confirmed
"#{location.postcode} #{location.startdate.blank? || location.startdate.before?(Time.zone.now) ? 'has been' : 'will be'} added to this scheme" "#{location.postcode} #{location.startdate.blank? || location.startdate.before?(Time.zone.now) ? 'has been' : 'will be'} added to this scheme"

4
app/helpers/schemes_helper.rb

@ -15,6 +15,10 @@ module SchemesHelper
return govuk_button_link_to "Reactivate this scheme", scheme_new_reactivation_path(scheme) if scheme.deactivated? return govuk_button_link_to "Reactivate this scheme", scheme_new_reactivation_path(scheme) if scheme.deactivated?
end end
def delete_scheme_link(scheme)
govuk_button_link_to "Delete this scheme", scheme_delete_confirmation_path(scheme), warning: true
end
def owning_organisation_options(current_user) def owning_organisation_options(current_user)
all_orgs = Organisation.all.map { |org| OpenStruct.new(id: org.id, name: org.name) } all_orgs = Organisation.all.map { |org| OpenStruct.new(id: org.id, name: org.name) }
user_org = [OpenStruct.new(id: current_user.organisation_id, name: current_user.organisation.name)] user_org = [OpenStruct.new(id: current_user.organisation_id, name: current_user.organisation.name)]

4
app/models/form/lettings/questions/location_id.rb

@ -20,7 +20,7 @@ class Form::Lettings::Questions::LocationId < ::Form::Question
answer_opts = {} answer_opts = {}
return answer_opts unless ActiveRecord::Base.connected? return answer_opts unless ActiveRecord::Base.connected?
Location.started_in_2_weeks.select(:id, :postcode, :name).each_with_object(answer_opts) do |location, hsh| Location.visible.started_in_2_weeks.select(:id, :postcode, :name).each_with_object(answer_opts) do |location, hsh|
hsh[location.id.to_s] = { "value" => location.postcode, "hint" => location.name } hsh[location.id.to_s] = { "value" => location.postcode, "hint" => location.name }
hsh hsh
end end
@ -29,7 +29,7 @@ class Form::Lettings::Questions::LocationId < ::Form::Question
def displayed_answer_options(lettings_log, _user = nil) def displayed_answer_options(lettings_log, _user = nil)
return {} unless lettings_log.scheme return {} unless lettings_log.scheme
scheme_location_ids = lettings_log.scheme.locations.confirmed.pluck(:id) scheme_location_ids = lettings_log.scheme.locations.visible.confirmed.pluck(:id)
answer_options.select { |k, _v| scheme_location_ids.include?(k.to_i) } answer_options.select { |k, _v| scheme_location_ids.include?(k.to_i) }
end end

7
app/models/form/lettings/questions/nationality_all.rb

@ -15,4 +15,11 @@ class Form::Lettings::Questions::NationalityAll < ::Form::Question
end end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 36, 2024 => 35 }.freeze QUESTION_NUMBER_FROM_YEAR = { 2023 => 36, 2024 => 35 }.freeze
def label_from_value(value)
return unless value
return "Tenant prefers not to say" if value.to_i.zero?
answer_options[value.to_s]["name"]
end
end end

10
app/models/form/lettings/questions/scheme_id.rb

@ -19,8 +19,8 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question
answer_opts = { "" => "Select an option" } answer_opts = { "" => "Select an option" }
return answer_opts unless ActiveRecord::Base.connected? return answer_opts unless ActiveRecord::Base.connected?
Scheme.select(:id, :service_name, :primary_client_group, Scheme.visible.select(:id, :service_name, :primary_client_group,
:secondary_client_group).each_with_object(answer_opts) do |scheme, hsh| :secondary_client_group).each_with_object(answer_opts) do |scheme, hsh|
hsh[scheme.id.to_s] = scheme hsh[scheme.id.to_s] = scheme
hsh hsh
end end
@ -29,10 +29,10 @@ class Form::Lettings::Questions::SchemeId < ::Form::Question
def displayed_answer_options(lettings_log, _user = nil) def displayed_answer_options(lettings_log, _user = nil)
organisation = lettings_log.owning_organisation || lettings_log.created_by&.organisation organisation = lettings_log.owning_organisation || lettings_log.created_by&.organisation
schemes = if organisation schemes = if organisation
Scheme.includes(:locations).select(:id).where(owning_organisation_id: organisation.id, Scheme.visible.includes(:locations).select(:id).where(owning_organisation_id: organisation.id,
confirmed: true) confirmed: true)
else else
Scheme.includes(:locations).select(:id).where(confirmed: true) Scheme.visible.includes(:locations).select(:id).where(confirmed: true)
end end
filtered_scheme_ids = schemes.joins(:locations).merge(Location.started_in_2_weeks).map(&:id) filtered_scheme_ids = schemes.joins(:locations).merge(Location.started_in_2_weeks).map(&:id)
answer_options.select do |k, _v| answer_options.select do |k, _v|

7
app/models/form/sales/questions/nationality_all.rb

@ -21,4 +21,11 @@ class Form::Sales::Questions::NationalityAll < ::Form::Question
@buyer_index == 1 ? 26 : 34 @buyer_index == 1 ? 26 : 34
end end
end end
def label_from_value(value)
return unless value
return "Buyer prefers not to say" if value.to_i.zero?
answer_options[value.to_s]["name"]
end
end end

7
app/models/location.rb

@ -79,6 +79,8 @@ class Location < ApplicationRecord
.where.not(id: activating_soon.pluck(:id)) .where.not(id: activating_soon.pluck(:id))
} }
scope :visible, -> { where(discarded_at: nil) }
LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h
enum local_authorities: LOCAL_AUTHORITIES enum local_authorities: LOCAL_AUTHORITIES
@ -138,6 +140,7 @@ class Location < ApplicationRecord
end end
def status_at(date) def status_at(date)
return :deleted if discarded_at.present?
return :incomplete unless confirmed return :incomplete unless confirmed
return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date
return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date
@ -190,6 +193,10 @@ class Location < ApplicationRecord
LocalAuthority.where(id: [la.id] + la.linked_local_authority_ids) LocalAuthority.where(id: [la.id] + la.linked_local_authority_ids)
end end
def discard!
update!(discarded_at: Time.zone.now)
end
private private
PIO = PostcodeService.new PIO = PostcodeService.new

10
app/models/scheme.rb

@ -77,6 +77,8 @@ class Scheme < ApplicationRecord
.where.not(id: activating_soon.pluck(:id)) .where.not(id: activating_soon.pluck(:id))
} }
scope :visible, -> { where(discarded_at: nil) }
validate :validate_confirmed validate :validate_confirmed
validate :validate_owning_organisation validate :validate_owning_organisation
@ -229,7 +231,7 @@ class Scheme < ApplicationRecord
end end
def validate_confirmed def validate_confirmed
required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units deactivation_date deactivation_date_type startdate] required_attributes = attribute_names - %w[id created_at updated_at old_id old_visible_id confirmed end_date sensitive secondary_client_group total_units deactivation_date deactivation_date_type startdate discarded_at]
if confirmed == true if confirmed == true
required_attributes.any? do |attribute| required_attributes.any? do |attribute|
@ -264,6 +266,7 @@ class Scheme < ApplicationRecord
end end
def status_at(date) def status_at(date)
return :deleted if discarded_at.present?
return :incomplete unless confirmed && locations.confirmed.any? return :incomplete unless confirmed && locations.confirmed.any?
return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date return :deactivated if open_deactivation&.deactivation_date.present? && date >= open_deactivation.deactivation_date
return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date return :deactivating_soon if open_deactivation&.deactivation_date.present? && date < open_deactivation.deactivation_date
@ -288,4 +291,9 @@ class Scheme < ApplicationRecord
def deactivates_in_a_long_time? def deactivates_in_a_long_time?
status_at(6.months.from_now) == :deactivating_soon status_at(6.months.from_now) == :deactivating_soon
end end
def discard!
update!(discarded_at: Time.zone.now)
locations.each(&:discard!)
end
end end

17
app/policies/location_policy.rb

@ -26,6 +26,17 @@ class LocationPolicy
user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner user.data_coordinator? && scheme_owned_by_user_org_or_stock_owner
end end
def delete_confirmation?
delete?
end
def delete?
return false unless user.support?
return false unless location.status == :incomplete || location.status == :deactivated
!has_any_logs_in_editable_collection_period
end
%w[ %w[
update_postcode? update_postcode?
update_local_authority? update_local_authority?
@ -75,4 +86,10 @@ private
def scheme_owned_by_user_org_or_stock_owner def scheme_owned_by_user_org_or_stock_owner
scheme&.owning_organisation == user.organisation || user.organisation.stock_owners.exists?(scheme&.owning_organisation_id) scheme&.owning_organisation == user.organisation || user.organisation.stock_owners.exists?(scheme&.owning_organisation_id)
end end
def has_any_logs_in_editable_collection_period
editable_from_date = FormHandler.instance.earliest_open_for_editing_collection_start_date
LettingsLog.where(location_id: location.id).after_date(editable_from_date).or(LettingsLog.where(startdate: nil, location_id: location.id)).any?
end
end end

17
app/policies/scheme_policy.rb

@ -65,9 +65,26 @@ class SchemePolicy
end end
end end
def delete_confirmation?
delete?
end
def delete?
return false unless user.support?
return false unless scheme.status == :incomplete || scheme.status == :deactivated
!has_any_logs_in_editable_collection_period
end
private private
def scheme_owned_by_user_org_or_stock_owner def scheme_owned_by_user_org_or_stock_owner
scheme&.owning_organisation == user.organisation || user.organisation.stock_owners.exists?(scheme&.owning_organisation_id) scheme&.owning_organisation == user.organisation || user.organisation.stock_owners.exists?(scheme&.owning_organisation_id)
end end
def has_any_logs_in_editable_collection_period
editable_from_date = FormHandler.instance.earliest_open_for_editing_collection_start_date
LettingsLog.where(scheme_id: scheme.id).after_date(editable_from_date).or(LettingsLog.where(startdate: nil, scheme_id: scheme.id)).any?
end
end end

8
app/services/feature_toggle.rb

@ -26,4 +26,12 @@ class FeatureToggle
def self.service_moved? def self.service_moved?
false false
end end
def self.delete_scheme_enabled?
!Rails.env.production?
end
def self.delete_location_enabled?
!Rails.env.production?
end
end end

3
app/views/locations/check_answers.html.erb

@ -42,6 +42,9 @@
<% if LocationPolicy.new(current_user, @location).create? %> <% if LocationPolicy.new(current_user, @location).create? %>
<div class="govuk-button-group"> <div class="govuk-button-group">
<%= govuk_button_to "Save and return to locations", scheme_location_confirm_path(@scheme, @location, route: params[:route]), method: :patch %> <%= govuk_button_to "Save and return to locations", scheme_location_confirm_path(@scheme, @location, route: params[:route]), method: :patch %>
<% if LocationPolicy.new(current_user, @location).delete? && FeatureToggle.delete_location_enabled? %>
<%= delete_location_link(@location) %>
<% end %>
<%= govuk_button_link_to "Cancel", scheme_locations_path(@scheme), secondary: true %> <%= govuk_button_link_to "Cancel", scheme_locations_path(@scheme), secondary: true %>
</div> </div>
<% end %> <% end %>

24
app/views/locations/delete_confirmation.html.erb

@ -0,0 +1,24 @@
<% content_for :before_content do %>
<% content_for :title, "Are you sure you want to delete this location?" %>
<%= govuk_back_link(href: :back) %>
<% end %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds-from-desktop">
<span class="govuk-caption-xl">Delete <%= @location.postcode %></span>
<h1 class="govuk-heading-xl">
<%= content_for(:title) %>
</h1>
<%= govuk_warning_text(text: "You will not be able to undo this action.") %>
<div class="govuk-button-group">
<%= govuk_button_to(
"Delete this location",
scheme_location_delete_path(@scheme, @location),
method: :delete,
) %>
<%= govuk_button_link_to "Cancel", scheme_location_path(@scheme, @location), html: { method: :get }, secondary: true %>
</div>
</div>
</div>

11
app/views/locations/show.html.erb

@ -19,7 +19,12 @@
<%= summary_list.with_row do |row| %> <%= summary_list.with_row do |row| %>
<% row.with_key { attr[:name] } %> <% row.with_key { attr[:name] } %>
<% if attr[:attribute].eql?("status") %> <% if attr[:attribute].eql?("status") %>
<%= row.with_value { status_tag_from_resource(@location) } %> <%= row.with_value do %>
<%= details_html({ name: "Status", value: status_tag_from_resource(@location), id: "status" }) %>
<% if @location.deactivated? && current_user.support? && !LocationPolicy.new(current_user, @location).delete? %>
<span class="app-!-colour-muted">This location was active in an open or editable collection year, and cannot be deleted.</span>
<% end %>
<% end %>
<% elsif attr[:attribute].eql?("postcode") && @location.is_la_inferred %> <% elsif attr[:attribute].eql?("postcode") && @location.is_la_inferred %>
<% row.with_value do %> <% row.with_value do %>
<%= details_html(attr) %> <%= details_html(attr) %>
@ -45,3 +50,7 @@
<% if LocationPolicy.new(current_user, @location).deactivate? %> <% if LocationPolicy.new(current_user, @location).deactivate? %>
<%= toggle_location_link(@location) %> <%= toggle_location_link(@location) %>
<% end %> <% end %>
<% if LocationPolicy.new(current_user, @location).delete? && FeatureToggle.delete_location_enabled? %>
<%= delete_location_link(@location) %>
<% end %>

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

@ -23,4 +23,8 @@
<% if SchemePolicy.new(current_user, @scheme).create? %> <% if SchemePolicy.new(current_user, @scheme).create? %>
<%= f.govuk_submit button_label %> <%= f.govuk_submit button_label %>
<% end %> <% end %>
<% if SchemePolicy.new(current_user, @scheme).delete? && FeatureToggle.delete_scheme_enabled? %>
<%= delete_scheme_link(@scheme) %>
<% end %>
<% end %> <% end %>

24
app/views/schemes/delete_confirmation.html.erb

@ -0,0 +1,24 @@
<% content_for :before_content do %>
<% content_for :title, "Are you sure you want to delete this scheme?" %>
<%= govuk_back_link(href: :back) %>
<% end %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds-from-desktop">
<span class="govuk-caption-xl">Delete <%= @scheme.service_name %></span>
<h1 class="govuk-heading-xl">
<%= content_for(:title) %>
</h1>
<%= govuk_warning_text(text: "You will not be able to undo this action.") %>
<div class="govuk-button-group">
<%= govuk_button_to(
"Delete this scheme",
scheme_delete_path(@scheme),
method: :delete,
) %>
<%= govuk_button_link_to "Cancel", scheme_path(@scheme), html: { method: :get }, secondary: true %>
</div>
</div>
</div>

7
app/views/schemes/show.html.erb

@ -29,6 +29,9 @@
<% if @scheme.confirmed? && @scheme.locations.confirmed.none? && LocationPolicy.new(current_user, @scheme.locations.new).create? %> <% if @scheme.confirmed? && @scheme.locations.confirmed.none? && LocationPolicy.new(current_user, @scheme.locations.new).create? %>
<span class="app-!-colour-muted">Complete this scheme by adding a location using the <%= govuk_link_to("‘locations’ tab", scheme_locations_path(@scheme)) %>.</span> <span class="app-!-colour-muted">Complete this scheme by adding a location using the <%= govuk_link_to("‘locations’ tab", scheme_locations_path(@scheme)) %>.</span>
<% end %> <% end %>
<% if @scheme.deactivated? && current_user.support? && !SchemePolicy.new(current_user, @scheme).delete? %>
<span class="app-!-colour-muted">This scheme was active in an open or editable collection year, and cannot be deleted.</span>
<% end %>
</dd> </dd>
</div> </div>
<% elsif attr[:id] != "secondary_client_group" || @scheme.has_other_client_group == "Yes" %> <% elsif attr[:id] != "secondary_client_group" || @scheme.has_other_client_group == "Yes" %>
@ -49,3 +52,7 @@
<% if SchemePolicy.new(current_user, @scheme).deactivate? %> <% if SchemePolicy.new(current_user, @scheme).deactivate? %>
<%= toggle_scheme_link(@scheme) %> <%= toggle_scheme_link(@scheme) %>
<% end %> <% end %>
<% if SchemePolicy.new(current_user, @scheme).delete? && FeatureToggle.delete_scheme_enabled? %>
<%= delete_scheme_link(@scheme) %>
<% end %>

2
config/locales/en.yml

@ -196,6 +196,8 @@ en:
duplicate_sets: duplicate_sets:
one: "There is %{count} set of duplicate logs" one: "There is %{count} set of duplicate logs"
other: "There are %{count} sets of duplicate logs" other: "There are %{count} sets of duplicate logs"
location_deleted: "%{postcode} has been deleted."
scheme_deleted: "%{service_name} has been deleted."
validations: validations:
organisation: organisation:

4
config/routes.rb

@ -79,6 +79,8 @@ Rails.application.routes.draw do
patch "new-deactivation", to: "schemes#new_deactivation" patch "new-deactivation", to: "schemes#new_deactivation"
patch "deactivate", to: "schemes#deactivate" patch "deactivate", to: "schemes#deactivate"
patch "reactivate", to: "schemes#reactivate" patch "reactivate", to: "schemes#reactivate"
get "delete-confirmation", to: "schemes#delete_confirmation"
delete "delete", to: "schemes#delete"
collection do collection do
get "csv-download", to: "schemes#download_csv" get "csv-download", to: "schemes#download_csv"
@ -111,6 +113,8 @@ Rails.application.routes.draw do
patch "new-deactivation", to: "locations#new_deactivation" patch "new-deactivation", to: "locations#new_deactivation"
patch "deactivate", to: "locations#deactivate" patch "deactivate", to: "locations#deactivate"
patch "reactivate", to: "locations#reactivate" patch "reactivate", to: "locations#reactivate"
get "delete-confirmation", to: "locations#delete_confirmation"
delete "delete", to: "locations#delete"
end end
end end
get "scheme-changes", to: "schemes#changes" get "scheme-changes", to: "schemes#changes"

5
db/migrate/20240301125651_add_discarded_at_column.rb

@ -0,0 +1,5 @@
class AddDiscardedAtColumn < ActiveRecord::Migration[7.0]
def change
add_column :locations, :discarded_at, :datetime
end
end

5
db/migrate/20240304100017_add_discarded_at_column_to_schemes.rb

@ -0,0 +1,5 @@
class AddDiscardedAtColumnToSchemes < ActiveRecord::Migration[7.0]
def change
add_column :schemes, :discarded_at, :datetime
end
end

2
db/schema.rb

@ -374,6 +374,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_03_19_122706) do
t.string "location_admin_district" t.string "location_admin_district"
t.boolean "confirmed" t.boolean "confirmed"
t.boolean "is_la_inferred" t.boolean "is_la_inferred"
t.datetime "discarded_at"
t.index ["old_id"], name: "index_locations_on_old_id", unique: true t.index ["old_id"], name: "index_locations_on_old_id", unique: true
t.index ["scheme_id"], name: "index_locations_on_scheme_id" t.index ["scheme_id"], name: "index_locations_on_scheme_id"
end end
@ -722,6 +723,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_03_19_122706) do
t.integer "total_units" t.integer "total_units"
t.boolean "confirmed" t.boolean "confirmed"
t.datetime "startdate" t.datetime "startdate"
t.datetime "discarded_at"
t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id" t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id"
end end

2
spec/fixtures/files/lettings_log_csv_export_labels_23_during_24_period.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,assigned_to,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,single log,,,2023,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,,Yes,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,,
1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered assigned_to owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode declaration postcode_known uprn_known uprn uprn_confirmed address_line1_input postcode_full_input address_search_value_check uprn_selection address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered hhmemb pregnancy_value_check refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic national nationality_all ecstat1 details_known_2 relat2 partner_under_16_value_check multiple_partners_value_check age2 sex2 ecstat2 details_known_3 relat3 age3 sex3 ecstat3 details_known_4 relat4 age4 sex4 ecstat4 details_known_5 relat5 age5 sex5 ecstat5 details_known_6 relat6 age6 sex6 ecstat6 details_known_7 relat7 age7 sex7 ecstat7 details_known_8 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother reasonother_value_check prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr accessible_register letting_allocation_none referral referral_value_check net_income_known incref incfreq earnings net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed s.port@jeemayle.com false 2023-11-26T00:00:00+00:00 2024-04-01T00:00:00+01:00 single log 2023 address line 1 as entered address line 2 as entered town or city as entered county as entered AB1 2CD la as entered DLUHC DLUHC General needs Affordable rent general needs local authority No 2023-11-26 Affordable Rent Affordable Rent Rent to Buy No HIJKLMN ABCDEFG Yes Yes No fake address London NW9 5LL No Barnet E09000003 No Affordable rent basis Tenant abandoned property No 2 House Purpose built Yes 3 2023-11-24 Yes 2023-11-25 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 4 Yes 4 0 0 2 35 Female White Irish Tenant prefers not to say Other Yes Partner 32 Male Not seeking work No Prefers not to say Not known Prefers not to say Prefers not to say Yes Person prefers not to say Not known Person prefers not to say Person prefers not to say Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing Yes No No No No No No Yes No No Yes No No No No No No No Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing 2 No Yes TN23 6LZ Yes No Ashford E07000105 Yes Yes No No Yes No Tenant applied directly (no referral or nomination) Yes No Weekly 268 Universal Credit housing element Yes All No Every 2 weeks 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 Yes Yes 12.0 6.0

2
spec/fixtures/files/lettings_log_csv_export_labels_24.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,assigned_to,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate id,status,duplicate_set_id,created_by,is_dpo,created_at,updated_by,updated_at,creation_method,old_id,old_form_id,collection_start_year,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,assigned_to,owning_organisation_name,managing_organisation_name,needstype,lettype,renewal,startdate,renttype,renttype_detail,irproduct,irproduct_other,lar,tenancycode,propcode,declaration,postcode_known,uprn_known,uprn,uprn_confirmed,address_line1_input,postcode_full_input,address_search_value_check,uprn_selection,address_line1,address_line2,town_or_city,county,postcode_full,is_la_inferred,la_label,la,first_time_property_let_as_social_housing,unitletas,rsnvac,newprop,offered,unittype_gn,builtype,wchair,beds,voiddate,vacdays,void_date_value_check,majorrepairs,mrcdate,major_repairs_date_value_check,joint,startertenancy,tenancy,tenancyother,tenancylength,sheltered,hhmemb,pregnancy_value_check,refused,hhtype,totchild,totelder,totadult,age1,retirement_value_check,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,details_known_2,relat2,partner_under_16_value_check,multiple_partners_value_check,age2,sex2,ecstat2,details_known_3,relat3,age3,sex3,ecstat3,details_known_4,relat4,age4,sex4,ecstat4,details_known_5,relat5,age5,sex5,ecstat5,details_known_6,relat6,age6,sex6,ecstat6,details_known_7,relat7,age7,sex7,ecstat7,details_known_8,relat8,age8,sex8,ecstat8,armedforces,leftreg,reservist,preg_occ,housingneeds,housingneeds_type,housingneeds_a,housingneeds_b,housingneeds_c,housingneeds_f,housingneeds_g,housingneeds_h,housingneeds_other,illness,illness_type_4,illness_type_5,illness_type_2,illness_type_6,illness_type_7,illness_type_3,illness_type_9,illness_type_8,illness_type_1,illness_type_10,layear,waityear,reason,reasonother,reasonother_value_check,prevten,new_old,homeless,ppcodenk,ppostcode_full,previous_la_known,is_previous_la_inferred,prevloc_label,prevloc,reasonpref,rp_homeless,rp_insan_unsat,rp_medwel,rp_hardship,rp_dontknow,cbl,cap,chr,accessible_register,letting_allocation_none,referral,referral_value_check,net_income_known,incref,incfreq,earnings,net_income_value_check,hb,has_benefits,benefits,household_charge,nocharge,period,is_carehome,chcharge,wchchrg,carehome_charges_value_check,brent,wrent,rent_value_check,scharge,wscharge,pscharge,wpschrge,supcharg,wsupchrg,tcharge,wtcharge,scharge_value_check,pscharge_value_check,supcharg_value_check,hbrentshortfall,tshortfall_known,tshortfall,wtshortfall,scheme_code,scheme_service_name,scheme_sensitive,SCHTYPE,scheme_registered_under_care_act,scheme_owning_organisation_name,scheme_primary_client_group,scheme_has_other_client_group,scheme_secondary_client_group,scheme_support_type,scheme_intended_stay,scheme_created_at,location_code,location_postcode,location_name,location_units,location_type_of_unit,location_mobility_type,location_local_authority,location_startdate
,completed,,s.port@jeemayle.com,false,2023-11-26T00:00:00+00:00,,2024-04-01T00:00:00+01:00,single log,,,2023,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2023-11-26,Affordable Rent,Affordable Rent,Rent to Buy,,No,HIJKLMN,ABCDEFG,Yes,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2023-11-24,,,Yes,2023-11-25,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,,Yes,4,0,0,2,35,,Female,White,Irish,Tenant prefers not to say,,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,, ,in_progress,,s.port@jeemayle.com,false,2024-04-01T00:00:00+01:00,,2024-04-01T00:00:00+01:00,single log,,,2024,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,,DLUHC,DLUHC,General needs,Affordable rent general needs local authority,No,2024-04-01,Affordable Rent,Affordable Rent,,,No,HIJKLMN,ABCDEFG,Yes,Yes,No,,,,,,,fake address,,London,,NW9 5LL,No,Barnet,E09000003,No,Affordable rent basis,Tenant abandoned property,No,2,House,Purpose built,Yes,3,2024-03-30,,,Yes,2024-03-31,,Don’t know,Yes,Assured Shorthold Tenancy (AST) – Fixed term,,2,,4,,Yes,4,0,0,2,35,,Female,White,Irish,,Australia,Other,Yes,Partner,,,32,Male,Not seeking work,No,Prefers not to say,Not known,Prefers not to say,Prefers not to say,Yes,Person prefers not to say,Not known,Person prefers not to say,Person prefers not to say,,,,,,,,,,,,,,,,,,,,,Yes – the person is a current or former regular,No – they left up to and including 5 years ago,Yes,No,Yes,Fully wheelchair accessible housing,Yes,No,No,No,No,No,No,Yes,No,No,Yes,No,No,No,No,No,No,No,Less than 1 year,1 year but under 2 years,Loss of tied accommodation,,,Other supported housing,2,No,Yes,TN23 6LZ,Yes,No,Ashford,E07000105,Yes,,Yes,,,,No,No,Yes,No,,Tenant applied directly (no referral or nomination),,Yes,No,Weekly,268,,Universal Credit housing element,Yes,All,,No,Every 2 weeks,,,,,200.0,100.0,,50.0,25.0,40.0,20.0,35.0,17.5,325.0,162.5,,,,Yes,Yes,12.0,6.0,,,,,,,,,,,,,,,,,,,,

1 id status duplicate_set_id created_by is_dpo created_at updated_by updated_at creation_method old_id old_form_id collection_start_year address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered assigned_to owning_organisation_name managing_organisation_name needstype lettype renewal startdate renttype renttype_detail irproduct irproduct_other lar tenancycode propcode declaration postcode_known uprn_known uprn uprn_confirmed address_line1_input postcode_full_input address_search_value_check uprn_selection address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la first_time_property_let_as_social_housing unitletas rsnvac newprop offered unittype_gn builtype wchair beds voiddate vacdays void_date_value_check majorrepairs mrcdate major_repairs_date_value_check joint startertenancy tenancy tenancyother tenancylength sheltered hhmemb pregnancy_value_check refused hhtype totchild totelder totadult age1 retirement_value_check sex1 ethnic_group ethnic national nationality_all ecstat1 details_known_2 relat2 partner_under_16_value_check multiple_partners_value_check age2 sex2 ecstat2 details_known_3 relat3 age3 sex3 ecstat3 details_known_4 relat4 age4 sex4 ecstat4 details_known_5 relat5 age5 sex5 ecstat5 details_known_6 relat6 age6 sex6 ecstat6 details_known_7 relat7 age7 sex7 ecstat7 details_known_8 relat8 age8 sex8 ecstat8 armedforces leftreg reservist preg_occ housingneeds housingneeds_type housingneeds_a housingneeds_b housingneeds_c housingneeds_f housingneeds_g housingneeds_h housingneeds_other illness illness_type_4 illness_type_5 illness_type_2 illness_type_6 illness_type_7 illness_type_3 illness_type_9 illness_type_8 illness_type_1 illness_type_10 layear waityear reason reasonother reasonother_value_check prevten new_old homeless ppcodenk ppostcode_full previous_la_known is_previous_la_inferred prevloc_label prevloc reasonpref rp_homeless rp_insan_unsat rp_medwel rp_hardship rp_dontknow cbl cap chr accessible_register letting_allocation_none referral referral_value_check net_income_known incref incfreq earnings net_income_value_check hb has_benefits benefits household_charge nocharge period is_carehome chcharge wchchrg carehome_charges_value_check brent wrent rent_value_check scharge wscharge pscharge wpschrge supcharg wsupchrg tcharge wtcharge scharge_value_check pscharge_value_check supcharg_value_check hbrentshortfall tshortfall_known tshortfall wtshortfall scheme_code scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act scheme_owning_organisation_name scheme_primary_client_group scheme_has_other_client_group scheme_secondary_client_group scheme_support_type scheme_intended_stay scheme_created_at location_code location_postcode location_name location_units location_type_of_unit location_mobility_type location_local_authority location_startdate
2 completed in_progress s.port@jeemayle.com false 2023-11-26T00:00:00+00:00 2024-04-01T00:00:00+01:00 2024-04-01T00:00:00+01:00 single log 2023 2024 address line 1 as entered address line 2 as entered town or city as entered county as entered AB1 2CD la as entered DLUHC DLUHC General needs Affordable rent general needs local authority No 2023-11-26 2024-04-01 Affordable Rent Affordable Rent Rent to Buy No HIJKLMN ABCDEFG Yes Yes No fake address London NW9 5LL No Barnet E09000003 No Affordable rent basis Tenant abandoned property No 2 House Purpose built Yes 3 2023-11-24 2024-03-30 Yes 2023-11-25 2024-03-31 Don’t know Yes Assured Shorthold Tenancy (AST) – Fixed term 2 4 Yes 4 0 0 2 35 Female White Irish Tenant prefers not to say Australia Other Yes Partner 32 Male Not seeking work No Prefers not to say Not known Prefers not to say Prefers not to say Yes Person prefers not to say Not known Person prefers not to say Person prefers not to say Yes – the person is a current or former regular No – they left up to and including 5 years ago Yes No Yes Fully wheelchair accessible housing Yes No No No No No No Yes No No Yes No No No No No No No Less than 1 year 1 year but under 2 years Loss of tied accommodation Other supported housing 2 No Yes TN23 6LZ Yes No Ashford E07000105 Yes Yes No No Yes No Tenant applied directly (no referral or nomination) Yes No Weekly 268 Universal Credit housing element Yes All No Every 2 weeks 200.0 100.0 50.0 25.0 40.0 20.0 35.0 17.5 325.0 162.5 Yes Yes 12.0 6.0

2
spec/fixtures/files/sales_logs_csv_export_labels_23_during_24_period.csv vendored

@ -0,0 +1,2 @@
id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,assigned_to,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,,2023-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,single log,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,30,Non-binary,Buyer prefers not to say,17,United Kingdom,,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,Buyer prefers not to say,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0
1 id status duplicate_set_id created_at updated_at old_form_id collection_start_year creation_method is_dpo address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered assigned_to owning_organisation_name managing_organisation_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore noint privacynotice uprn uprn_confirmed address_line1_input postcode_full_input uprn_selection address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label beds proptype builtype pcodenk wchair age1 sex1 ethnic_group ethnic national nationality_all ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationalbuy2 nationality_all_buyer2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed 2023-12-08T00:00:00+00:00 2024-05-01T00:00:00+01:00 2023 single log false address line 1 as entered address line 2 as entered town or city as entered county as entered AB1 2CD la as entered DLUHC DLUHC billyboy@eyeklaud.com 8 12 2023 Yes - a discounted ownership scheme Right to Acquire (RTA) Yes Yes Yes 1 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet 2 Flat or maisonette Purpose built 0 Yes 30 Non-binary Buyer prefers not to say 17 United Kingdom Full-time - 30 hours or more Yes Partner 35 Non-binary Buyer prefers not to say Buyer prefers not to say Full-time - 30 hours or more Yes 3 Child 14 Non-binary Other Not known Non-binary In government training into work, such as New Deal Prefers not to say Not known Prefers not to say Prefers not to say Local authority tenant No No 1 1 1 1 Don't know Yes Yes No Yes Yes Yes 10000 Yes Yes 10000 Yes Don’t know No Yes No 10 110000.0 Yes 20000.0 Cambridge Building Society 10 Yes 80000.0 Yes 100.0 10000.0

2
spec/fixtures/files/sales_logs_csv_export_labels_24.csv vendored

@ -1,2 +1,2 @@
id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,assigned_to,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant id,status,duplicate_set_id,created_at,updated_at,old_form_id,collection_start_year,creation_method,is_dpo,address_line1_as_entered,address_line2_as_entered,town_or_city_as_entered,county_as_entered,postcode_full_as_entered,la_as_entered,assigned_to,owning_organisation_name,managing_organisation_name,created_by,day,month,year,purchid,ownershipsch,type,othtype,companybuy,buylivein,jointpur,jointmore,noint,privacynotice,uprn,uprn_confirmed,address_line1_input,postcode_full_input,uprn_selection,address_line1,address_line2,town_or_city,county,pcode1,pcode2,la_known,la,la_label,beds,proptype,builtype,pcodenk,wchair,age1,sex1,ethnic_group,ethnic,national,nationality_all,ecstat1,buy1livein,relat2,age2,sex2,ethnic_group2,ethnicbuy2,nationalbuy2,nationality_all_buyer2,ecstat2,buy2livein,hholdcount,relat3,age3,sex3,ecstat3,relat4,age4,sex4,ecstat4,relat5,age5,sex5,ecstat5,relat6,age6,sex6,ecstat6,prevten,ppcodenk,ppostc1,ppostc2,previous_la_known,prevloc,prevloc_label,pregyrha,pregother,pregla,pregghb,pregblank,buy2living,prevtenbuy2,hhregres,hhregresstill,armedforcesspouse,disabled,wheel,income1nk,income1,inc1mort,income2nk,income2,inc2mort,hb,savingsnk,savings,prevown,prevshared,proplen,staircase,stairbought,stairowned,staircasesale,resale,exday,exmonth,exyear,hoday,homonth,hoyear,lanomagr,soctenant,frombeds,fromprop,socprevten,value,equity,mortgageused,mortgage,mortgagelender,mortgagelenderother,mortlen,extrabor,deposit,cashdis,mrent,has_mscharge,mscharge,discount,grant
,completed,,2023-12-08T00:00:00+00:00,2024-05-01T00:00:00+01:00,,2023,single log,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,,DLUHC,DLUHC,billyboy@eyeklaud.com,8,12,2023,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,30,Non-binary,Buyer prefers not to say,17,United Kingdom,,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,Buyer prefers not to say,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,No,,,No,,,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0 ,in_progress,,2024-05-01T00:00:00+01:00,2024-05-01T00:00:00+01:00,,2024,single log,false,address line 1 as entered,address line 2 as entered,town or city as entered,county as entered,AB1 2CD,la as entered,,DLUHC,DLUHC,billyboy@eyeklaud.com,1,5,2024,,Yes - a discounted ownership scheme,Right to Acquire (RTA),,,,Yes,Yes,Yes,1,,,,,,Address line 1,,Town or city,,SW1A,1AA,1,E09000003,Barnet,2,Flat or maisonette,Purpose built,0,Yes,30,Non-binary,Buyer prefers not to say,17,,Australia,Full-time - 30 hours or more,Yes,Partner,35,Non-binary,Buyer prefers not to say,,13,,Full-time - 30 hours or more,Yes,3,Child,14,Non-binary,Child under 16,Other,Not known,Non-binary,"In government training into work, such as New Deal",Prefers not to say,Not known,Prefers not to say,Prefers not to say,,,,,Local authority tenant,Yes,SW1A,1AA,Yes,E09000003,Barnet,1,1,1,1,,Don't know,,Yes,Yes,No,Yes,Yes,Yes,10000,Yes,Yes,10000,Yes,"Don’t know ",No,,Yes,No,10,,,,,,,,,,,,,,,,,110000.0,,Yes,20000.0,Cambridge Building Society,,10,Yes,80000.0,,,Yes,100.0,,10000.0

1 id status duplicate_set_id created_at updated_at old_form_id collection_start_year creation_method is_dpo address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered assigned_to owning_organisation_name managing_organisation_name created_by day month year purchid ownershipsch type othtype companybuy buylivein jointpur jointmore noint privacynotice uprn uprn_confirmed address_line1_input postcode_full_input uprn_selection address_line1 address_line2 town_or_city county pcode1 pcode2 la_known la la_label beds proptype builtype pcodenk wchair age1 sex1 ethnic_group ethnic national nationality_all ecstat1 buy1livein relat2 age2 sex2 ethnic_group2 ethnicbuy2 nationalbuy2 nationality_all_buyer2 ecstat2 buy2livein hholdcount relat3 age3 sex3 ecstat3 relat4 age4 sex4 ecstat4 relat5 age5 sex5 ecstat5 relat6 age6 sex6 ecstat6 prevten ppcodenk ppostc1 ppostc2 previous_la_known prevloc prevloc_label pregyrha pregother pregla pregghb pregblank buy2living prevtenbuy2 hhregres hhregresstill armedforcesspouse disabled wheel income1nk income1 inc1mort income2nk income2 inc2mort hb savingsnk savings prevown prevshared proplen staircase stairbought stairowned staircasesale resale exday exmonth exyear hoday homonth hoyear lanomagr soctenant frombeds fromprop socprevten value equity mortgageused mortgage mortgagelender mortgagelenderother mortlen extrabor deposit cashdis mrent has_mscharge mscharge discount grant
2 completed in_progress 2023-12-08T00:00:00+00:00 2024-05-01T00:00:00+01:00 2024-05-01T00:00:00+01:00 2023 2024 single log false address line 1 as entered address line 2 as entered town or city as entered county as entered AB1 2CD la as entered DLUHC DLUHC billyboy@eyeklaud.com 8 1 12 5 2023 2024 Yes - a discounted ownership scheme Right to Acquire (RTA) Yes Yes Yes 1 Address line 1 Town or city SW1A 1AA 1 E09000003 Barnet 2 Flat or maisonette Purpose built 0 Yes 30 Non-binary Buyer prefers not to say 17 United Kingdom Australia Full-time - 30 hours or more Yes Partner 35 Non-binary Buyer prefers not to say Buyer prefers not to say 13 Full-time - 30 hours or more Yes 3 Child 14 Non-binary Child under 16 Other Not known Non-binary In government training into work, such as New Deal Prefers not to say Not known Prefers not to say Prefers not to say Local authority tenant No Yes SW1A 1AA No Yes E09000003 Barnet 1 1 1 1 Don't know Yes Yes No Yes Yes Yes 10000 Yes Yes 10000 Yes Don’t know No Yes No 10 110000.0 Yes 20000.0 Cambridge Building Society 10 Yes 80000.0 Yes 100.0 10000.0

12
spec/models/form/lettings/questions/location_id_spec.rb

@ -80,6 +80,18 @@ RSpec.describe Form::Lettings::Questions::LocationId, type: :model do
end end
end end
context "and all the locations are deleted" do
before do
FactoryBot.create(:location, scheme:, discarded_at: Time.utc(2022, 5, 12))
FactoryBot.create(:location, scheme:, discarded_at: Time.utc(2022, 5, 12))
lettings_log.update!(scheme:)
end
it "the displayed_answer_options is an empty hash" do
expect(question.displayed_answer_options(lettings_log)).to eq({})
end
end
context "and all but one of the locations have a startdate more than 2 weeks in the future" do context "and all but one of the locations have a startdate more than 2 weeks in the future" do
before do before do
FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 13)) FactoryBot.create(:location, scheme:, startdate: Time.utc(2022, 5, 13))

13
spec/models/form/lettings/questions/scheme_id_spec.rb

@ -147,6 +147,19 @@ RSpec.describe Form::Lettings::Questions::SchemeId, type: :model do
expect(question.displayed_answer_options(lettings_log)).to eq(expected_answer) expect(question.displayed_answer_options(lettings_log)).to eq(expected_answer)
end end
end end
context "when the scheme is deleted" do
let(:scheme) { FactoryBot.create(:scheme, owning_organisation: organisation, discarded_at: Time.zone.yesterday) }
before do
FactoryBot.create(:location, startdate: Time.zone.tomorrow, scheme:)
end
it "has the correct answer_options based on the schemes the user's organisation owns or manages" do
expected_answer = { "" => "Select an option" }
expect(question.displayed_answer_options(lettings_log)).to eq(expected_answer)
end
end
end end
context "when there are no schemes with locations" do context "when there are no schemes with locations" do

8
spec/models/scheme_spec.rb

@ -304,6 +304,14 @@ RSpec.describe Scheme, type: :model do
expect(scheme.status).to eq(:activating_soon) expect(scheme.status).to eq(:activating_soon)
end end
end end
context "when scheme has discarded_at value" do
let(:scheme) { FactoryBot.create(:scheme, discarded_at: Time.zone.now) }
it "returns deleted" do
expect(scheme.status).to eq(:deleted)
end
end
end end
describe "status_at" do describe "status_at" do

92
spec/policies/location_policy_spec.rb

@ -0,0 +1,92 @@
require "rails_helper"
RSpec.describe LocationPolicy do
subject(:policy) { described_class }
let(:data_provider) { FactoryBot.create(:user, :data_provider) }
let(:data_coordinator) { FactoryBot.create(:user, :data_coordinator) }
let(:support) { FactoryBot.create(:user, :support) }
permissions :delete? do
let(:location) { FactoryBot.create(:location) }
context "with active location" do
it "does not allow deleting a location as a provider" do
expect(policy).not_to permit(data_provider, location)
end
it "does not allow allows deleting a location as a coordinator" do
expect(policy).not_to permit(data_coordinator, location)
end
it "does not allow deleting a location as a support user" do
expect(policy).not_to permit(support, location)
end
end
context "with incomplete location" do
before do
location.update!(units: nil)
end
it "does not allow deleting a location as a provider" do
expect(policy).not_to permit(data_provider, location)
end
it "does not allow allows deleting a location as a coordinator" do
expect(policy).not_to permit(data_coordinator, location)
end
it "allows deleting a location as a support user" do
expect(policy).to permit(support, location)
end
end
context "with deactivated location" do
before do
location.location_deactivation_periods << create(:location_deactivation_period, deactivation_date: Time.zone.local(2024, 4, 10), location:)
location.save!
Timecop.freeze(Time.utc(2024, 4, 10))
log = create(:lettings_log, scheme: location.scheme, location:)
log.startdate = Time.zone.local(2022, 10, 10)
log.save!(validate: false)
end
after do
Timecop.unfreeze
end
context "and associated logs in editable collection period" do
before do
create(:lettings_log, scheme: location.scheme, location:)
end
it "does not allow deleting a location as a provider" do
expect(policy).not_to permit(data_provider, location)
end
it "does not allow allows deleting a location as a coordinator" do
expect(policy).not_to permit(data_coordinator, location)
end
it "does not allow deleting a location as a support user" do
expect(policy).not_to permit(support, location)
end
end
context "and no associated logs in editable collection period" do
it "does not allow deleting a location as a provider" do
expect(policy).not_to permit(data_provider, location)
end
it "does not allow allows deleting a location as a coordinator" do
expect(policy).not_to permit(data_coordinator, location)
end
it "allows deleting a location as a support user" do
expect(policy).to permit(support, location)
end
end
end
end
end

94
spec/policies/scheme_policy_spec.rb

@ -0,0 +1,94 @@
require "rails_helper"
RSpec.describe SchemePolicy do
subject(:policy) { described_class }
let(:data_provider) { create(:user, :data_provider) }
let(:data_coordinator) { create(:user, :data_coordinator) }
let(:support) { create(:user, :support) }
permissions :delete? do
let(:scheme) { create(:scheme) }
before do
create(:location, scheme:)
end
context "with active scheme" do
it "does not allow deleting a scheme as a provider" do
expect(policy).not_to permit(data_provider, scheme)
end
it "does not allow allows deleting a scheme as a coordinator" do
expect(policy).not_to permit(data_coordinator, scheme)
end
it "does not allow deleting a scheme as a support user" do
expect(policy).not_to permit(support, scheme)
end
end
context "with incomplete scheme" do
let(:scheme) { create(:scheme, :incomplete) }
it "does not allow deleting a scheme as a provider" do
expect(policy).not_to permit(data_provider, scheme)
end
it "does not allow allows deleting a scheme as a coordinator" do
expect(policy).not_to permit(data_coordinator, scheme)
end
it "allows deleting a scheme as a support user" do
expect(policy).to permit(support, scheme)
end
end
context "with deactivated scheme" do
before do
scheme.scheme_deactivation_periods << create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2024, 4, 10), scheme:)
scheme.save!
Timecop.freeze(Time.utc(2024, 4, 10))
log = create(:lettings_log, :sh, owning_organisation: scheme.owning_organisation, scheme:)
log.startdate = Time.zone.local(2022, 10, 10)
log.save!(validate: false)
end
after do
Timecop.unfreeze
end
context "and associated logs in editable collection period" do
before do
create(:lettings_log, :sh, owning_organisation: scheme.owning_organisation, scheme:, startdate: Time.zone.local(2024, 4, 9))
end
it "does not allow deleting a scheme as a provider" do
expect(policy).not_to permit(data_provider, scheme)
end
it "does not allow allows deleting a scheme as a coordinator" do
expect(policy).not_to permit(data_coordinator, scheme)
end
it "does not allow deleting a scheme as a support user" do
expect(policy).not_to permit(support, scheme)
end
end
context "and no associated logs in editable collection period" do
it "does not allow deleting a scheme as a provider" do
expect(policy).not_to permit(data_provider, scheme)
end
it "does not allow allows deleting a scheme as a coordinator" do
expect(policy).not_to permit(data_coordinator, scheme)
end
it "allows deleting a scheme as a support user" do
expect(policy).to permit(support, scheme)
end
end
end
end
end

270
spec/requests/locations_controller_spec.rb

@ -1405,6 +1405,23 @@ RSpec.describe LocationsController, type: :request do
expect(page).to have_content("Check your answers") expect(page).to have_content("Check your answers")
end end
context "with an active location" do
it "does not render delete this location" do
expect(location.status).to eq(:active)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end
context "with an incomplete location" do
it "renders delete this location" do
location.update!(units: nil)
get "/schemes/#{scheme.id}/locations/#{location.id}/check-answers"
expect(location.reload.status).to eq(:incomplete)
expect(page).to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end
context "when location is confirmed" do context "when location is confirmed" do
let(:params) { { location: { confirmed: true } } } let(:params) { { location: { confirmed: true } } }
@ -1825,6 +1842,11 @@ RSpec.describe LocationsController, type: :request do
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
expect(page).to have_link("Reactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/new-reactivation") expect(page).to have_link("Reactivate this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/new-reactivation")
end end
it "does not render delete this location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end end
context "with location that's deactivating soon" do context "with location that's deactivating soon" do
@ -1883,6 +1905,108 @@ RSpec.describe LocationsController, type: :request do
end end
end end
end end
context "when signed in as a support user" do
let(:user) { create(:user, :support) }
let(:scheme) { create(:scheme) }
let(:location) { create(:location, scheme:) }
let(:add_deactivations) { location.location_deactivation_periods << location_deactivation_period }
before do
Timecop.freeze(Time.utc(2022, 10, 10))
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
add_deactivations
location.save!
get "/schemes/#{scheme.id}/locations/#{location.id}"
end
after do
Timecop.unfreeze
end
context "with active location" do
let(:add_deactivations) {}
it "does not render delete this location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
it "does not render informative text about deleting the location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_content("This location was active in an open or editable collection year, and cannot be deleted.")
end
end
context "with deactivated location" do
let(:location_deactivation_period) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), location:) }
it "renders delete this location" do
expect(response).to have_http_status(:ok)
expect(page).to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
context "and associated logs in editable collection period" do
before do
create(:lettings_log, :sh, location:, scheme:, startdate: Time.zone.local(2022, 9, 9), owning_organisation: user.organisation)
get "/schemes/#{scheme.id}/locations/#{location.id}"
end
it "does not render delete this location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
it "adds informative text about deleting the location" do
expect(response).to have_http_status(:ok)
expect(page).to have_content("This location was active in an open or editable collection year, and cannot be deleted.")
end
end
end
context "with incomplete location" do
let(:add_deactivations) {}
before do
location.update!(units: nil)
get "/schemes/#{scheme.id}/locations/#{location.id}"
end
it "renders delete this location" do
expect(location.reload.status).to eq(:incomplete)
expect(response).to have_http_status(:ok)
expect(page).to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end
context "with location that's deactivating soon" do
let(:location_deactivation_period) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12), location:) }
it "does not render delete this location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end
context "with location that's deactivating in more than 6 months" do
let(:location_deactivation_period) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2023, 6, 12), location:) }
it "does not render delete this location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end
context "with location that's reactivating soon" do
let(:location_deactivation_period) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 12), reactivation_date: Time.zone.local(2022, 10, 12), location:) }
it "does not render delete this location" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this location", href: "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation")
end
end
end
end end
describe "#reactivate" do describe "#reactivate" do
@ -2040,4 +2164,150 @@ RSpec.describe LocationsController, type: :request do
end end
end end
end end
describe "#delete-confirmation" do
let(:scheme) { create(:scheme, owning_organisation: user.organisation) }
let(:location) { create(:location, scheme:, created_at: Time.zone.local(2022, 4, 1)) }
before do
get "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation"
end
context "when not signed in" do
it "redirects to the sign in page" do
expect(response).to redirect_to("/account/sign-in")
end
end
context "when signed in" do
before do
Timecop.freeze(Time.utc(2022, 10, 10))
location.location_deactivation_periods << create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), location:)
location.save!
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
get "/schemes/#{scheme.id}/locations/#{location.id}/delete-confirmation"
end
after do
Timecop.unfreeze
end
context "with a data provider user" do
let(:user) { create(:user) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a data coordinator user" do
let(:user) { create(:user, :data_coordinator) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a support user user" do
let(:user) { create(:user, :support) }
it "shows the correct title" do
expect(page.find("h1").text).to include "Are you sure you want to delete this location?"
end
it "shows a warning to the user" do
expect(page).to have_selector(".govuk-warning-text", text: "You will not be able to undo this action")
end
it "shows a button to delete the selected location" do
expect(page).to have_selector("form.button_to button", text: "Delete this location")
end
it "the delete location button submits the correct data to the correct path" do
form_containing_button = page.find("form.button_to")
expect(form_containing_button[:action]).to eq scheme_location_delete_path(scheme, location)
expect(form_containing_button).to have_field "_method", type: :hidden, with: "delete"
end
it "shows a cancel link with the correct style" do
expect(page).to have_selector("a.govuk-button--secondary", text: "Cancel")
end
it "shows cancel link that links back to the location page" do
expect(page).to have_link(text: "Cancel", href: scheme_location_path(scheme, location))
end
end
end
end
describe "#delete" do
let(:scheme) { create(:scheme, owning_organisation: user.organisation) }
let(:location) { create(:location, scheme:, name: "Location to delete", created_at: Time.zone.local(2022, 4, 1)) }
before do
Timecop.freeze(Time.utc(2022, 10, 10))
location.location_deactivation_periods << create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), location:)
location.save!
delete "/schemes/#{scheme.id}/locations/#{location.id}/delete"
end
after do
Timecop.unfreeze
end
context "when not signed in" do
it "redirects to the sign in page" do
expect(response).to redirect_to("/account/sign-in")
end
end
context "when signed in" do
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
delete "/schemes/#{scheme.id}/locations/#{location.id}/delete"
end
context "with a data provider user" do
let(:user) { create(:user) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a data coordinator user" do
let(:user) { create(:user, :data_coordinator) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a support user user" do
let(:user) { create(:user, :support) }
it "deletes the location" do
location.reload
expect(location.status).to eq(:deleted)
expect(location.discarded_at).not_to be nil
end
it "redirects to the scheme locations list and displays a notice that the location has been deleted" do
expect(response).to redirect_to scheme_locations_path(scheme)
follow_redirect!
expect(page).to have_selector(".govuk-notification-banner--success")
expect(page).to have_selector(".govuk-notification-banner--success", text: "has been deleted.")
end
it "does not display the deleted location" do
expect(response).to redirect_to scheme_locations_path(scheme)
follow_redirect!
expect(page).not_to have_content("Location to delete")
end
end
end
end
end end

5
spec/requests/organisations_controller_spec.rb

@ -44,6 +44,7 @@ RSpec.describe OrganisationsController, type: :request do
let(:user) { create(:user, :support) } let(:user) { create(:user, :support) }
let!(:schemes) { create_list(:scheme, 5) } let!(:schemes) { create_list(:scheme, 5) }
let!(:same_org_scheme) { create(:scheme, owning_organisation: user.organisation) } let!(:same_org_scheme) { create(:scheme, owning_organisation: user.organisation) }
let!(:deleted_scheme) { create(:scheme, owning_organisation: user.organisation, discarded_at: Time.zone.yesterday) }
before do before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false) allow(user).to receive(:need_two_factor_authentication?).and_return(false)
@ -131,6 +132,10 @@ RSpec.describe OrganisationsController, type: :request do
end end
end end
it "does not show deleted schemes" do
expect(page).not_to have_content(deleted_scheme.id_to_display)
end
context "when searching" do context "when searching" do
let!(:searched_scheme) { create(:scheme, owning_organisation: user.organisation) } let!(:searched_scheme) { create(:scheme, owning_organisation: user.organisation) }
let(:search_param) { searched_scheme.id } let(:search_param) { searched_scheme.id }

286
spec/requests/schemes_controller_spec.rb

@ -56,6 +56,19 @@ RSpec.describe SchemesController, type: :request do
end end
end end
context "when there are deleted schemes" do
let!(:deleted_scheme) { create(:scheme, service_name: "deleted", discarded_at: Time.zone.yesterday, owning_organisation: user.organisation) }
before do
get "/schemes"
end
it "does not show deleted schemes" do
follow_redirect!
expect(page).not_to have_content(deleted_scheme.id_to_display)
end
end
context "when parent organisation has schemes" do context "when parent organisation has schemes" do
let(:parent_organisation) { create(:organisation) } let(:parent_organisation) { create(:organisation) }
let!(:parent_schemes) { create_list(:scheme, 5, owning_organisation: parent_organisation) } let!(:parent_schemes) { create_list(:scheme, 5, owning_organisation: parent_organisation) }
@ -191,6 +204,18 @@ RSpec.describe SchemesController, type: :request do
expect(page).to have_content("Schemes") expect(page).to have_content("Schemes")
end end
context "when there are deleted schemes" do
let!(:deleted_scheme) { create(:scheme, service_name: "deleted", discarded_at: Time.zone.yesterday, owning_organisation: user.organisation) }
before do
get "/schemes"
end
it "does not show deleted schemes" do
expect(page).not_to have_content(deleted_scheme.id_to_display)
end
end
describe "scheme and location csv downloads" do describe "scheme and location csv downloads" do
let!(:same_org_scheme) { create(:scheme, owning_organisation: user.organisation) } let!(:same_org_scheme) { create(:scheme, owning_organisation: user.organisation) }
let!(:specific_organisation) { create(:organisation) } let!(:specific_organisation) { create(:organisation) }
@ -577,6 +602,11 @@ RSpec.describe SchemesController, type: :request do
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
expect(page).to have_link("Reactivate this scheme", href: "/schemes/#{scheme.id}/new-reactivation") expect(page).to have_link("Reactivate this scheme", href: "/schemes/#{scheme.id}/new-reactivation")
end end
it "does not render delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
end end
context "with scheme that's deactivating soon" do context "with scheme that's deactivating soon" do
@ -712,6 +742,92 @@ RSpec.describe SchemesController, type: :request do
expect(page).to have_content(specific_scheme.support_type) expect(page).to have_content(specific_scheme.support_type)
expect(page).to have_content(specific_scheme.intended_stay) expect(page).to have_content(specific_scheme.intended_stay)
end end
context "when looking at scheme details" do
let!(:scheme) { create(:scheme, owning_organisation: user.organisation) }
let(:add_deactivations) { scheme.scheme_deactivation_periods << scheme_deactivation_period }
before do
create(:location, scheme:)
Timecop.freeze(Time.utc(2022, 10, 10))
sign_in user
add_deactivations
scheme.save!
get "/schemes/#{scheme.id}"
end
after do
Timecop.unfreeze
end
context "with active scheme" do
let(:add_deactivations) {}
it "does not render delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
it "does not render informative text about deleting the scheme" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_content("This scheme was active in an open or editable collection year, and cannot be deleted.")
end
end
context "with deactivated scheme" do
let(:scheme_deactivation_period) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), scheme:) }
it "renders delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
context "and associated logs in editable collection period" do
before do
create(:lettings_log, :sh, scheme:, startdate: Time.zone.local(2022, 9, 9), owning_organisation: user.organisation)
get "/schemes/#{scheme.id}"
end
it "does not render delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
it "adds informative text about deleting the scheme" do
expect(response).to have_http_status(:ok)
expect(page).to have_content("This scheme was active in an open or editable collection year, and cannot be deleted.")
end
end
end
context "with scheme that's deactivating soon" do
let(:scheme_deactivation_period) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12), scheme:) }
it "does not render delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
end
context "with scheme that's deactivating in more than 6 months" do
let(:scheme_deactivation_period) { create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2023, 5, 12), scheme:) }
it "does not render delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).not_to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
end
context "with incomplete scheme" do
let(:add_deactivations) {}
let!(:scheme) { create(:scheme, :incomplete, owning_organisation: user.organisation) }
it "renders delete this scheme" do
expect(response).to have_http_status(:ok)
expect(page).to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
end
end
end end
end end
@ -2132,6 +2248,7 @@ RSpec.describe SchemesController, type: :request do
let!(:scheme) { create(:scheme) } let!(:scheme) { create(:scheme) }
before do before do
create(:location, scheme:)
allow(user).to receive(:need_two_factor_authentication?).and_return(false) allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user sign_in user
get "/schemes/#{scheme.id}/check-answers" get "/schemes/#{scheme.id}/check-answers"
@ -2141,6 +2258,22 @@ RSpec.describe SchemesController, type: :request do
expect(response).to have_http_status(:ok) expect(response).to have_http_status(:ok)
expect(page).to have_content("Check your changes before creating this scheme") expect(page).to have_content("Check your changes before creating this scheme")
end end
context "with an active scheme" do
it "does not render delete this scheme" do
expect(scheme.status).to eq(:active)
expect(page).not_to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
end
context "with an incomplete scheme" do
let(:scheme) { create(:scheme, :incomplete) }
it "renders delete this scheme" do
expect(scheme.reload.status).to eq(:incomplete)
expect(page).to have_link("Delete this scheme", href: "/schemes/#{scheme.id}/delete-confirmation")
end
end
end end
end end
@ -2641,4 +2774,157 @@ RSpec.describe SchemesController, type: :request do
end end
end end
end end
describe "#delete-confirmation" do
let(:scheme) { create(:scheme, owning_organisation: user.organisation) }
before do
Timecop.freeze(Time.utc(2022, 10, 10))
scheme.scheme_deactivation_periods << create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), scheme:)
scheme.save!
get "/schemes/#{scheme.id}/delete-confirmation"
end
after do
Timecop.unfreeze
end
context "when not signed in" do
it "redirects to the sign in page" do
expect(response).to redirect_to("/account/sign-in")
end
end
context "when signed in" do
before do
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
get "/schemes/#{scheme.id}/delete-confirmation"
end
context "with a data provider user" do
let(:user) { create(:user) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a data coordinator user" do
let(:user) { create(:user, :data_coordinator) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a support user user" do
let(:user) { create(:user, :support) }
it "shows the correct title" do
expect(page.find("h1").text).to include "Are you sure you want to delete this scheme?"
end
it "shows a warning to the user" do
expect(page).to have_selector(".govuk-warning-text", text: "You will not be able to undo this action")
end
it "shows a button to delete the selected scheme" do
expect(page).to have_selector("form.button_to button", text: "Delete this scheme")
end
it "the delete scheme button submits the correct data to the correct path" do
form_containing_button = page.find("form.button_to")
expect(form_containing_button[:action]).to eq scheme_delete_path(scheme)
expect(form_containing_button).to have_field "_method", type: :hidden, with: "delete"
end
it "shows a cancel link with the correct style" do
expect(page).to have_selector("a.govuk-button--secondary", text: "Cancel")
end
it "shows cancel link that links back to the scheme page" do
expect(page).to have_link(text: "Cancel", href: scheme_path(scheme))
end
end
end
end
describe "#delete" do
let(:scheme) { create(:scheme, service_name: "Scheme to delete", owning_organisation: user.organisation) }
let!(:locations) { create_list(:location, 2, scheme:, created_at: Time.zone.local(2022, 4, 1)) }
before do
delete "/schemes/#{scheme.id}/delete"
end
context "when not signed in" do
it "redirects to the sign in page" do
expect(response).to redirect_to("/account/sign-in")
end
end
context "when signed in" do
before do
Timecop.freeze(Time.utc(2022, 10, 10))
scheme.scheme_deactivation_periods << create(:scheme_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), scheme:)
scheme.save!
allow(user).to receive(:need_two_factor_authentication?).and_return(false)
sign_in user
delete "/schemes/#{scheme.id}/delete"
end
after do
Timecop.unfreeze
end
context "with a data provider user" do
let(:user) { create(:user) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a data coordinator user" do
let(:user) { create(:user, :data_coordinator) }
it "returns 401 unauthorized" do
expect(response).to have_http_status(:unauthorized)
end
end
context "with a support user user" do
let(:user) { create(:user, :support) }
it "deletes the scheme" do
scheme.reload
expect(scheme.status).to eq(:deleted)
expect(scheme.discarded_at).not_to be nil
end
it "deletes associated locations" do
locations.each do |location|
location.reload
expect(location.status).to eq(:deleted)
expect(location.discarded_at).not_to be nil
end
end
it "redirects to the schemes list and displays a notice that the scheme has been deleted" do
expect(response).to redirect_to schemes_organisation_path(scheme.owning_organisation)
follow_redirect!
expect(page).to have_selector(".govuk-notification-banner--success")
expect(page).to have_selector(".govuk-notification-banner--success", text: "Scheme to delete has been deleted.")
end
it "does not display the deleted scheme" do
expect(response).to redirect_to schemes_organisation_path(scheme.owning_organisation)
follow_redirect!
expect(page).not_to have_link("Scheme to delete")
end
end
end
end
end end

35
spec/services/csv/lettings_log_csv_service_spec.rb

@ -172,14 +172,35 @@ RSpec.describe Csv::LettingsLogCsvService do
context "when the current form is 2024" do context "when the current form is 2024" do
let(:now) { Time.zone.local(2024, 4, 1) } let(:now) { Time.zone.local(2024, 4, 1) }
it "exports the CSV with 2024 ordering and all values correct" do context "and the log is for 2024 collection period" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels_24.csv") let(:fixed_time) { Time.zone.local(2024, 4, 1) }
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute| before do
index = csv.first.index(attribute) log.update!(national: nil)
csv.second[index] = nil log.update!(nationality_all: 36)
end
it "exports the CSV with 2024 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels_24.csv")
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "and the log is for 2023 collection period" do
it "exports the CSV with 2024 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels_23_during_24_period.csv")
values_to_delete = %w[id vacdays]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
end end

35
spec/services/csv/sales_log_csv_service_spec.rb

@ -168,14 +168,35 @@ RSpec.describe Csv::SalesLogCsvService do
context "when the current form is 2024" do context "when the current form is 2024" do
let(:now) { Time.zone.local(2024, 5, 1) } let(:now) { Time.zone.local(2024, 5, 1) }
it "exports the CSV with the 2024 ordering and all values correct" do context "and the log is for 2024 collection period" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_labels_24.csv") let(:fixed_time) { Time.zone.local(2024, 5, 1) }
values_to_delete = %w[id]
values_to_delete.each do |attribute| before do
index = csv.first.index(attribute) log.update!(national: nil)
csv.second[index] = nil log.update!(nationality_all: 36)
end
it "exports the CSV with the 2024 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_labels_24.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end
end
context "and the log is for 2023 collection period" do
it "exports the CSV with the 2024 ordering and all values correct" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_labels_23_during_24_period.csv")
values_to_delete = %w[id]
values_to_delete.each do |attribute|
index = csv.first.index(attribute)
csv.second[index] = nil
end
expect(csv).to eq expected_content
end end
expect(csv).to eq expected_content
end end
end end

2
spec/views/locations/show.html.erb_spec.rb

@ -51,6 +51,7 @@ RSpec.describe "locations/show.html.erb" do
assign(:location, location) assign(:location, location)
allow(view).to receive(:current_user).and_return(user) allow(view).to receive(:current_user).and_return(user)
allow(location).to receive(:deactivated?).and_return(false)
render render
@ -62,6 +63,7 @@ RSpec.describe "locations/show.html.erb" do
assign(:location, location) assign(:location, location)
allow(view).to receive(:current_user).and_return(user) allow(view).to receive(:current_user).and_return(user)
allow(location).to receive(:deactivated?).and_return(false)
render render

Loading…
Cancel
Save