Browse Source

Merge branch 'main' into VersionUpdate

pull/2867/head
Rachael Booth 6 months ago
parent
commit
9dc23271ed
  1. 8
      Gemfile
  2. 221
      Gemfile.lock
  3. 2
      app/components/bulk_upload_error_row_component.html.erb
  4. 2
      app/components/search_component.html.erb
  5. 2
      app/controllers/lettings_logs_controller.rb
  6. 2
      app/controllers/logs_controller.rb
  7. 4
      app/controllers/organisations_controller.rb
  8. 2
      app/controllers/sales_logs_controller.rb
  9. 12
      app/controllers/sessions_controller.rb
  10. 4
      app/helpers/filters_helper.rb
  11. 2
      app/helpers/logs_helper.rb
  12. 6
      app/models/bulk_upload.rb
  13. 2
      app/models/csv_download.rb
  14. 1
      app/models/form/lettings/questions/offered.rb
  15. 2
      app/models/forms/bulk_upload_lettings_resume/fix_choice.rb
  16. 2
      app/models/forms/bulk_upload_sales_resume/fix_choice.rb
  17. 7
      app/models/location.rb
  18. 12
      app/models/log.rb
  19. 4
      app/models/merge_request.rb
  20. 2
      app/models/organisation.rb
  21. 18
      app/models/scheme.rb
  22. 2
      app/models/user.rb
  23. 4
      app/models/validations/soft_validations.rb
  24. 6
      app/services/exports/organisation_export_service.rb
  25. 1
      app/services/exports/user_export_service.rb
  26. 16
      app/services/feature_toggle.rb
  27. 2
      app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2024.html.erb
  28. 2
      app/views/bulk_upload_lettings_resume/deletion_report.html.erb
  29. 2
      app/views/bulk_upload_lettings_soft_validations_check/confirm.html.erb
  30. 2
      app/views/bulk_upload_sales_resume/deletion_report.html.erb
  31. 2
      app/views/bulk_upload_sales_soft_validations_check/confirm.html.erb
  32. 4
      app/views/bulk_upload_shared/_moved_user_banner.html.erb
  33. 2
      app/views/bulk_upload_shared/guidance.html.erb
  34. 2
      app/views/devise/sessions/new.html.erb
  35. 2
      app/views/locations/check_answers.html.erb
  36. 2
      app/views/locations/show.html.erb
  37. 2
      app/views/schemes/check_answers.html.erb
  38. 2
      app/views/schemes/show.html.erb
  39. 2
      app/views/users/show.html.erb
  40. 8
      bin/rubocop
  41. 3
      bin/setup
  42. 13
      config/application.rb
  43. 19
      config/environments/development.rb
  44. 78
      config/environments/production.rb
  45. 34
      config/environments/test.rb
  46. 6
      config/initializers/assets.rb
  47. 13
      config/initializers/content_security_policy.rb
  48. 6
      config/initializers/filter_parameter_logging.rb
  49. 20
      config/initializers/permissions_policy.rb
  50. 4
      config/locales/en.yml
  51. 17
      config/locales/test.en.yml
  52. 4
      config/locales/validations/sales/2024/bulk_upload.en.yml
  53. 48
      config/puma.rb
  54. 22
      db/migrate/20241206142942_add_service_name_to_active_storage_blobs.active_storage.rb
  55. 28
      db/migrate/20241206142943_create_active_storage_variant_records.active_storage.rb
  56. 8
      db/migrate/20241206142944_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
  57. 2
      db/schema.rb
  58. 12
      db/seeds.rb
  59. 2
      package.json
  60. 2
      spec/controllers/errors_controller_spec.rb
  61. 6
      spec/features/organisation_spec.rb
  62. 4
      spec/features/schemes_spec.rb
  63. 6
      spec/features/user_spec.rb
  64. 2
      spec/fixtures/exports/user.xml
  65. 28
      spec/models/validations/soft_validations_spec.rb
  66. 2
      spec/rails_helper.rb
  67. 2
      spec/requests/auth/passwords_controller_spec.rb
  68. 8
      spec/requests/bulk_upload_lettings_results_controller_spec.rb
  69. 2
      spec/requests/bulk_upload_lettings_soft_validations_check_controller_spec.rb
  70. 8
      spec/requests/bulk_upload_sales_results_controller_spec.rb
  71. 2
      spec/requests/bulk_upload_sales_soft_validations_check_controller_spec.rb
  72. 32
      spec/requests/delete_logs_controller_spec.rb
  73. 2
      spec/requests/form_controller_spec.rb
  74. 8
      spec/requests/lettings_logs_controller_spec.rb
  75. 32
      spec/requests/locations_controller_spec.rb
  76. 20
      spec/requests/merge_requests_controller_spec.rb
  77. 2
      spec/requests/notifications_controller_spec.rb
  78. 6
      spec/requests/organisations_controller_spec.rb
  79. 6
      spec/requests/sales_logs_controller_spec.rb
  80. 28
      spec/requests/schemes_controller_spec.rb
  81. 58
      spec/requests/users_controller_spec.rb
  82. 2
      spec/services/exports/organisation_export_service_spec.rb
  83. 2
      spec/services/exports/user_export_service_spec.rb
  84. 70
      spec/services/merge/merge_organisations_service_spec.rb
  85. 12
      yarn.lock

8
Gemfile

@ -6,11 +6,11 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.1.4"
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem "rails", "~> 7.0.8.7"
gem "rails", "~> 7.2.2"
# Use postgresql as the database for Active Record
gem "pg", "~> 1.1"
# Use Puma as the app server
gem "puma", "~> 5.6"
gem "puma", "~> 6.4"
# The modern asset pipeline for Rails [https://github.com/rails/propshaft]
gem "propshaft"
# Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails]
@ -44,7 +44,7 @@ gem "view_component", "~> 3.9"
# Use the AWS S3 SDK as storage mechanism
gem "aws-sdk-s3"
# Track changes to models for auditing or versioning.
gem "paper_trail"
gem "paper_trail", "~> 15.2"
# Store active record objects in version whodunnits
gem "paper_trail-globalid"
@ -90,7 +90,7 @@ group :development do
# Display performance information such as SQL time and flame graphs for each request in your browser.
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
gem "erb_lint", require: false
gem "rack-mini-profiler", "~> 2.0"
gem "rack-mini-profiler", "~> 3.3.0"
gem "rubocop-govuk", "4.3.0", require: false
gem "rubocop-performance", require: false
gem "rubocop-rails", require: false

221
Gemfile.lock

@ -1,75 +1,81 @@
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.8.7)
actionpack (= 7.0.8.7)
activesupport (= 7.0.8.7)
actioncable (7.2.2.1)
actionpack (= 7.2.2.1)
activesupport (= 7.2.2.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.8.7)
actionpack (= 7.0.8.7)
activejob (= 7.0.8.7)
activerecord (= 7.0.8.7)
activestorage (= 7.0.8.7)
activesupport (= 7.0.8.7)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.8.7)
actionpack (= 7.0.8.7)
actionview (= 7.0.8.7)
activejob (= 7.0.8.7)
activesupport (= 7.0.8.7)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.8.7)
actionview (= 7.0.8.7)
activesupport (= 7.0.8.7)
rack (~> 2.0, >= 2.2.4)
zeitwerk (~> 2.6)
actionmailbox (7.2.2.1)
actionpack (= 7.2.2.1)
activejob (= 7.2.2.1)
activerecord (= 7.2.2.1)
activestorage (= 7.2.2.1)
activesupport (= 7.2.2.1)
mail (>= 2.8.0)
actionmailer (7.2.2.1)
actionpack (= 7.2.2.1)
actionview (= 7.2.2.1)
activejob (= 7.2.2.1)
activesupport (= 7.2.2.1)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.2.2.1)
actionview (= 7.2.2.1)
activesupport (= 7.2.2.1)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.2)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.8.7)
actionpack (= 7.0.8.7)
activerecord (= 7.0.8.7)
activestorage (= 7.0.8.7)
activesupport (= 7.0.8.7)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (7.2.2.1)
actionpack (= 7.2.2.1)
activerecord (= 7.2.2.1)
activestorage (= 7.2.2.1)
activesupport (= 7.2.2.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.8.7)
activesupport (= 7.0.8.7)
actionview (7.2.2.1)
activesupport (= 7.2.2.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.8.7)
activesupport (= 7.0.8.7)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.2.2.1)
activesupport (= 7.2.2.1)
globalid (>= 0.3.6)
activemodel (7.0.8.7)
activesupport (= 7.0.8.7)
activemodel-serializers-xml (1.0.2)
activemodel (> 5.x)
activesupport (> 5.x)
activemodel (7.2.2.1)
activesupport (= 7.2.2.1)
activemodel-serializers-xml (1.0.3)
activemodel (>= 5.0.0.a)
activesupport (>= 5.0.0.a)
builder (~> 3.1)
activerecord (7.0.8.7)
activemodel (= 7.0.8.7)
activesupport (= 7.0.8.7)
activestorage (7.0.8.7)
actionpack (= 7.0.8.7)
activejob (= 7.0.8.7)
activerecord (= 7.0.8.7)
activesupport (= 7.0.8.7)
activerecord (7.2.2.1)
activemodel (= 7.2.2.1)
activesupport (= 7.2.2.1)
timeout (>= 0.4.0)
activestorage (7.2.2.1)
actionpack (= 7.2.2.1)
activejob (= 7.2.2.1)
activerecord (= 7.2.2.1)
activesupport (= 7.2.2.1)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.8.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
activesupport (7.2.2.1)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
tzinfo (~> 2.0)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
ast (2.4.2)
@ -104,6 +110,7 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
base64 (0.2.0)
bcrypt (3.1.20)
benchmark (0.4.0)
better_html (2.0.2)
actionview (>= 6.0)
activesupport (>= 6.0)
@ -111,7 +118,7 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.6)
bigdecimal (3.1.8)
bindex (0.8.1)
bootsnap (1.18.3)
msgpack (~> 1.2)
@ -149,6 +156,7 @@ GEM
crass (1.0.6)
cssbundling-rails (1.4.0)
railties (>= 6.0.0)
csv (3.3.0)
date (3.4.1)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
@ -170,6 +178,7 @@ GEM
dotenv-rails (3.0.2)
dotenv (= 3.0.2)
railties (>= 6.1)
drb (2.2.1)
dumb_delegator (1.0.0)
encryptor (3.0.0)
erb_lint (0.5.0)
@ -184,10 +193,10 @@ GEM
tzinfo
event_stream_parser (1.0.0)
excon (0.111.0)
factory_bot (6.4.6)
factory_bot (6.5.0)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.3)
factory_bot (~> 6.4)
factory_bot_rails (6.4.4)
factory_bot (~> 6.5)
railties (>= 5.0.0)
faker (3.2.3)
i18n (>= 1.8.11, < 2)
@ -222,6 +231,10 @@ GEM
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
iniparse (1.5.0)
io-console (0.8.0)
irb (1.14.1)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jmespath (1.6.2)
jsbundling-rails (1.3.0)
railties (>= 6.0.0)
@ -246,6 +259,7 @@ GEM
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.6.2)
loofah (2.23.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
@ -288,7 +302,7 @@ GEM
iniparse (~> 1.4)
rexml (~> 3.2)
pagy (9.3.2)
paper_trail (15.1.0)
paper_trail (15.2.0)
activerecord (>= 6.1)
request_store (~> 1.4)
paper_trail-globalid (0.2.0)
@ -313,34 +327,41 @@ GEM
pry-byebug (3.10.1)
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
psych (5.2.1)
date
stringio
public_suffix (5.0.4)
puma (5.6.9)
puma (6.5.0)
nio4r (~> 2.0)
pundit (2.3.1)
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.8.1)
rack (2.2.10)
rack (3.1.8)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
rack-mini-profiler (2.3.4)
rack-mini-profiler (3.3.1)
rack (>= 1.2.0)
rack-session (2.0.0)
rack (>= 3.0.0)
rack-test (2.1.0)
rack (>= 1.3)
rails (7.0.8.7)
actioncable (= 7.0.8.7)
actionmailbox (= 7.0.8.7)
actionmailer (= 7.0.8.7)
actionpack (= 7.0.8.7)
actiontext (= 7.0.8.7)
actionview (= 7.0.8.7)
activejob (= 7.0.8.7)
activemodel (= 7.0.8.7)
activerecord (= 7.0.8.7)
activestorage (= 7.0.8.7)
activesupport (= 7.0.8.7)
rackup (2.2.1)
rack (>= 3)
rails (7.2.2.1)
actioncable (= 7.2.2.1)
actionmailbox (= 7.2.2.1)
actionmailer (= 7.2.2.1)
actionpack (= 7.2.2.1)
actiontext (= 7.2.2.1)
actionview (= 7.2.2.1)
activejob (= 7.2.2.1)
activemodel (= 7.2.2.1)
activerecord (= 7.2.2.1)
activestorage (= 7.2.2.1)
activesupport (= 7.2.2.1)
bundler (>= 1.15.0)
railties (= 7.0.8.7)
railties (= 7.2.2.1)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
@ -348,31 +369,37 @@ GEM
rails-html-sanitizer (1.6.1)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails_admin (3.1.3)
rails_admin (3.3.0)
activemodel-serializers-xml (>= 1.0)
csv
kaminari (>= 0.14, < 2.0)
nested_form (~> 0.3)
rails (>= 6.0, < 8)
turbo-rails (~> 1.0)
railties (7.0.8.7)
actionpack (= 7.0.8.7)
activesupport (= 7.0.8.7)
method_source
rails (>= 6.0, < 9)
turbo-rails (>= 1.0, < 3)
railties (7.2.2.1)
actionpack (= 7.2.2.1)
activesupport (= 7.2.2.1)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.2.1)
randexp (0.1.7)
rb-fsevent (0.11.2)
rb-inotify (0.10.1)
ffi (~> 1.0)
rdoc (6.8.1)
psych (>= 4.0.0)
redcarpet (3.6.0)
redis (4.8.1)
redis-client (0.22.1)
connection_pool
regexp_parser (2.9.0)
request_store (1.6.0)
reline (0.5.12)
io-console (~> 0.5)
request_store (1.7.0)
rack (>= 1.4)
responders (3.1.1)
actionpack (>= 5.2)
@ -434,6 +461,7 @@ GEM
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
securerandom (0.4.0)
selenium-webdriver (4.18.1)
base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5)
@ -462,21 +490,22 @@ GEM
smart_properties (1.17.0)
stimulus-rails (1.3.3)
railties (>= 6.0.0)
stringio (3.1.2)
thor (1.3.2)
thread_safe (0.3.6)
timecop (0.9.8)
timeout (0.4.2)
turbo-rails (1.5.0)
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
activejob (>= 6.0.0)
railties (>= 6.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
uk_postcode (2.1.8)
unicode-display_width (2.5.0)
unread (0.13.1)
unread (0.14.0)
activerecord (>= 6.1)
uri (0.13.0)
useragent (0.16.11)
view_component (3.10.0)
activesupport (>= 5.2.0, < 8.0)
concurrent-ruby (~> 1.0)
@ -541,19 +570,19 @@ DEPENDENCIES
method_source (~> 1.1)
notifications-ruby-client
overcommit (>= 0.37.0)
paper_trail
paper_trail (~> 15.2)
paper_trail-globalid
parallel_tests
pg (~> 1.1)
possessive
propshaft
pry-byebug
puma (~> 5.6)
puma (~> 6.4)
pundit
rack (>= 2.2.6.3)
rack-attack
rack-mini-profiler (~> 2.0)
rails (~> 7.0.8.7)
rack-mini-profiler (~> 3.3.0)
rails (~> 7.2.2)
rails_admin (~> 3.1)
redcarpet (~> 3.6)
redis (~> 4.8)

2
app/components/bulk_upload_error_row_component.html.erb

@ -38,7 +38,7 @@
<% if potential_errors.any? %>
<h2 class="govuk-heading-m">Potential errors</h2>
<p class="govuk-body">The following groups of cells might have conflicting data. Check the answers and fix any incorrect data.<br><br>If the answers are correct, fix the critical errors and reupload the file. You'll need to confirm that the following data is correct when the file only contains potential errors.</p>
<p class="govuk-body">The following groups of cells might have conflicting data. Check the answers and fix any incorrect data.<br><br>If the answers are correct, fix the critical errors and upload the file again. You'll need to confirm that the following data is correct when the file only contains potential errors.</p>
<%= govuk_table(html_attributes: { class: "no-bottom-border" }) do |table| %>
<%= table.with_head do |head| %>
<% head.with_row do |row| %>

2
app/components/search_component.html.erb

@ -1,4 +1,4 @@
<%= form_with model: @user, url: path(current_user), method: "get", local: true do |f| %>
<%= form_with url: path(current_user), method: "get", local: true do |f| %>
<div class="app-search govuk-!-margin-bottom-4">
<%= f.govuk_text_field :search,
form_group: {

2
app/controllers/lettings_logs_controller.rb

@ -22,7 +22,7 @@ class LettingsLogsController < LogsController
@total_count = all_logs.size
@unresolved_count = all_logs.unresolved.assigned_to(current_user).count
@filter_type = "lettings_logs"
@duplicate_sets_count = FeatureToggle.duplicate_summary_enabled? && !current_user.support? ? duplicate_sets_count(current_user, current_user.organisation) : 0
@duplicate_sets_count = !current_user.support? ? duplicate_sets_count(current_user, current_user.organisation) : 0
render "logs/index"
end

2
app/controllers/logs_controller.rb

@ -38,7 +38,7 @@ private
API_ACTIONS = %w[create show update].freeze
def json_api_request?
API_ACTIONS.include?(request["action"]) && request.format.json?
API_ACTIONS.include?(params["action"]) && request.format.json?
end
def authenticate

4
app/controllers/organisations_controller.rb

@ -186,7 +186,7 @@ class OrganisationsController < ApplicationController
@total_count = organisation_logs.size
@log_type = :lettings
@filter_type = "lettings_logs"
@duplicate_sets_count = FeatureToggle.duplicate_summary_enabled? ? duplicate_sets_count(current_user, @organisation) : 0
@duplicate_sets_count = duplicate_sets_count(current_user, @organisation)
render "logs", layout: "application"
end
@ -218,7 +218,7 @@ class OrganisationsController < ApplicationController
@total_count = organisation_logs.size
@log_type = :sales
@filter_type = "sales_logs"
@duplicate_sets_count = FeatureToggle.duplicate_summary_enabled? ? duplicate_sets_count(current_user, @organisation) : 0
@duplicate_sets_count = duplicate_sets_count(current_user, @organisation)
render "logs", layout: "application"
end

2
app/controllers/sales_logs_controller.rb

@ -24,7 +24,7 @@ class SalesLogsController < LogsController
@searched = search_term.presence
@total_count = all_logs.size
@filter_type = "sales_logs"
@duplicate_sets_count = FeatureToggle.duplicate_summary_enabled? && !current_user.support? ? duplicate_sets_count(current_user, current_user.organisation) : 0
@duplicate_sets_count = !current_user.support? ? duplicate_sets_count(current_user, current_user.organisation) : 0
render "logs/index"
end

12
app/controllers/sessions_controller.rb

@ -1,20 +1,20 @@
class SessionsController < ApplicationController
def clear_filters
session[session_name_for(params[:filter_type])] = "{}"
path_params = params[:path_params].presence || {}
filter_path_params = params[:filter_path_params].presence || {}
if path_params[:organisation_id].present?
redirect_to send("#{params[:filter_type]}_organisation_path", id: path_params[:organisation_id], scheme_id: path_params[:scheme_id], search: path_params[:search])
if filter_path_params[:organisation_id].present?
redirect_to send("#{params[:filter_type]}_organisation_path", id: filter_path_params[:organisation_id], scheme_id: filter_path_params[:scheme_id], search: filter_path_params[:search])
elsif params[:filter_type].include?("bulk_uploads")
bulk_upload_type = params[:filter_type].split("_").first
uploading_organisation = params[:organisation_id].presence
if uploading_organisation.present?
redirect_to send("bulk_uploads_#{bulk_upload_type}_logs_path", search: path_params[:search], uploading_organisation:)
redirect_to send("bulk_uploads_#{bulk_upload_type}_logs_path", search: filter_path_params[:search], uploading_organisation:)
else
redirect_to send("bulk_uploads_#{bulk_upload_type}_logs_path", search: path_params[:search])
redirect_to send("bulk_uploads_#{bulk_upload_type}_logs_path", search: filter_path_params[:search])
end
else
redirect_to send("#{params[:filter_type]}_path", scheme_id: path_params[:scheme_id], search: path_params[:search])
redirect_to send("#{params[:filter_type]}_path", scheme_id: filter_path_params[:scheme_id], search: filter_path_params[:search])
end
end

4
app/helpers/filters_helper.rb

@ -165,9 +165,9 @@ module FiltersHelper
applied_filters_count(filter_type).zero? ? "No filters applied" : "#{pluralize(applied_filters_count(filter_type), 'filter')} applied"
end
def reset_filters_link(filter_type, path_params = {})
def reset_filters_link(filter_type, filter_path_params = {})
if applied_filters_count(filter_type).positive?
govuk_link_to "Clear", clear_filters_path(filter_type:, path_params:)
govuk_link_to "Clear", clear_filters_path(filter_type:, filter_path_params:)
end
end

2
app/helpers/logs_helper.rb

@ -10,7 +10,7 @@ module LogsHelper
def bulk_upload_options(bulk_upload)
array = bulk_upload ? [bulk_upload.id] : []
array.index_with { |_bulk_upload_id| "With logs from bulk upload" }
array.index_with { |_bulk_upload_id| "Only logs from this bulk upload" }
end
def search_label_for_controller(controller)

6
app/models/bulk_upload.rb

@ -1,7 +1,7 @@
class BulkUpload < ApplicationRecord
enum log_type: { lettings: "lettings", sales: "sales" }
enum rent_type_fix_status: { not_applied: "not_applied", applied: "applied", not_needed: "not_needed" }
enum failure_reason: { blank_template: "blank_template", wrong_template: "wrong_template" }
enum :log_type, { lettings: "lettings", sales: "sales" }
enum :rent_type_fix_status, { not_applied: "not_applied", applied: "applied", not_needed: "not_needed" }
enum :failure_reason, { blank_template: "blank_template", wrong_template: "wrong_template" }
belongs_to :user

2
app/models/csv_download.rb

@ -1,5 +1,5 @@
class CsvDownload < ApplicationRecord
enum download_type: { lettings: "lettings", sales: "sales", schemes: "schemes", locations: "locations", combined: "combined" }
enum :download_type, { lettings: "lettings", sales: "sales", schemes: "schemes", locations: "locations", combined: "combined" }
belongs_to :user
belongs_to :organisation

1
app/models/form/lettings/questions/offered.rb

@ -7,7 +7,6 @@ class Form::Lettings::Questions::Offered < ::Form::Question
@check_answers_card_number = 0
@max = 150
@min = 0
@hint_text = I18n.t("hints.offered")
@step = 1
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end

2
app/models/forms/bulk_upload_lettings_resume/fix_choice.rb

@ -14,7 +14,7 @@ module Forms
def options
[
OpenStruct.new(id: "create-fix-inline", name: "Upload these logs and fix errors on CORE site"),
OpenStruct.new(id: "upload-again", name: "Fix errors in the CSV and re-upload"),
OpenStruct.new(id: "upload-again", name: "Fix errors in the CSV and upload the file again"),
]
end

2
app/models/forms/bulk_upload_sales_resume/fix_choice.rb

@ -14,7 +14,7 @@ module Forms
def options
[
OpenStruct.new(id: "create-fix-inline", name: "Upload these logs and fix errors on CORE site"),
OpenStruct.new(id: "upload-again", name: "Fix errors in the CSV and re-upload"),
OpenStruct.new(id: "upload-again", name: "Fix errors in the CSV and upload the file again"),
]
end

7
app/models/location.rb

@ -171,7 +171,8 @@ class Location < ApplicationRecord
DUPLICATE_LOCATION_ATTRIBUTES = %w[scheme_id postcode mobility_type].freeze
LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h
enum local_authorities: LOCAL_AUTHORITIES
attribute :local_authorities, :string
enum :local_authorities, LOCAL_AUTHORITIES
def self.local_authorities_for_current_year
LocalAuthority.all.active(Time.zone.today).england.map { |la| [la.code, la.name] }.to_h
end
@ -184,7 +185,7 @@ class Location < ApplicationRecord
"Missing": "X",
}.freeze
enum mobility_type: MOBILITY_TYPE
enum :mobility_type, MOBILITY_TYPE
TYPE_OF_UNIT = {
"Bungalow": 6,
@ -195,7 +196,7 @@ class Location < ApplicationRecord
"Shared house or hostel": 4,
}.freeze
enum type_of_unit: TYPE_OF_UNIT
enum :type_of_unit, TYPE_OF_UNIT
def self.find_by_id_on_multiple_fields(id)
return if id.nil?

12
app/models/log.rb

@ -18,14 +18,14 @@ class Log < ApplicationRecord
"pending" => 3,
"deleted" => 4,
}.freeze
enum status: STATUS
enum status_cache: STATUS, _prefix: true
enum :status, STATUS
enum :status_cache, STATUS, prefix: true
CREATION_METHOD = {
"single log" => 1,
"bulk upload" => 2,
}.freeze
enum creation_method: CREATION_METHOD, _prefix: true
enum :creation_method, CREATION_METHOD, prefix: true
scope :visible, -> { where(status: %w[not_started in_progress completed]) }
scope :exportable, -> { where(status: %w[not_started in_progress completed deleted]) }
@ -377,14 +377,14 @@ private
end
def reset_location_fields!
reset_location(is_la_inferred, "la", "is_la_inferred", "postcode_full", 1)
reset_log_location(is_la_inferred, "la", "is_la_inferred", "postcode_full", 1)
end
def reset_previous_location_fields!
reset_location(is_previous_la_inferred, "prevloc", "is_previous_la_inferred", "ppostcode_full", previous_la_known)
reset_log_location(is_previous_la_inferred, "prevloc", "is_previous_la_inferred", "ppostcode_full", previous_la_known)
end
def reset_location(is_inferred, la_key, is_inferred_key, postcode_key, is_la_known)
def reset_log_location(is_inferred, la_key, is_inferred_key, postcode_key, is_la_known)
if is_inferred || is_la_known != 1
self[la_key] = nil
end

4
app/models/merge_request.rb

@ -13,7 +13,9 @@ class MergeRequest < ApplicationRecord
request_merged: "request_merged",
deleted: "deleted",
}.freeze
enum status: STATUS
attribute :status, :string
enum :status, STATUS
scope :not_merged, -> { where(request_merged: [false, nil]) }
scope :merged, -> { where(request_merged: true) }

2
app/models/organisation.rb

@ -53,7 +53,7 @@ class Organisation < ApplicationRecord
PRP: 2,
}.freeze
enum provider_type: PROVIDER_TYPE
enum :provider_type, PROVIDER_TYPE
alias_method :la?, :LA?

18
app/models/scheme.rb

@ -145,7 +145,7 @@ class Scheme < ApplicationRecord
Yes: 1,
}.freeze
enum sensitive: SENSITIVE, _suffix: true
enum :sensitive, SENSITIVE, suffix: true
REGISTERED_UNDER_CARE_ACT = {
"Yes – registered care home providing nursing care": 4,
@ -154,7 +154,7 @@ class Scheme < ApplicationRecord
"No": 1,
}.freeze
enum registered_under_care_act: REGISTERED_UNDER_CARE_ACT
enum :registered_under_care_act, REGISTERED_UNDER_CARE_ACT
SCHEME_TYPE = {
"Direct Access Hostel": 5,
@ -164,7 +164,7 @@ class Scheme < ApplicationRecord
"Missing": 0,
}.freeze
enum scheme_type: SCHEME_TYPE, _suffix: true
enum :scheme_type, SCHEME_TYPE, suffix: true
SUPPORT_TYPE = {
"Missing": 0,
@ -175,7 +175,7 @@ class Scheme < ApplicationRecord
"Floating support": 6,
}.freeze
enum support_type: SUPPORT_TYPE, _suffix: true
enum :support_type, SUPPORT_TYPE, suffix: true
PRIMARY_CLIENT_GROUP = {
"Homeless families with support needs": "O",
@ -197,8 +197,8 @@ class Scheme < ApplicationRecord
"Missing": "X",
}.freeze
enum primary_client_group: PRIMARY_CLIENT_GROUP, _suffix: true
enum secondary_client_group: PRIMARY_CLIENT_GROUP, _suffix: true
enum :primary_client_group, PRIMARY_CLIENT_GROUP, suffix: true
enum :secondary_client_group, PRIMARY_CLIENT_GROUP, suffix: true
INTENDED_STAY = {
"Very short stay": "V",
@ -213,8 +213,8 @@ class Scheme < ApplicationRecord
Yes: 1,
}.freeze
enum intended_stay: INTENDED_STAY, _suffix: true
enum has_other_client_group: HAS_OTHER_CLIENT_GROUP, _suffix: true
enum :intended_stay, INTENDED_STAY, suffix: true
enum :has_other_client_group, HAS_OTHER_CLIENT_GROUP, suffix: true
ARRANGEMENT_TYPE = {
"The same organisation that owns the housing stock": "D",
@ -226,7 +226,7 @@ class Scheme < ApplicationRecord
DUPLICATE_SCHEME_ATTRIBUTES = %w[scheme_type registered_under_care_act primary_client_group secondary_client_group has_other_client_group support_type intended_stay].freeze
enum arrangement_type: ARRANGEMENT_TYPE, _suffix: true
enum :arrangement_type, ARRANGEMENT_TYPE, suffix: true
def self.find_by_id_on_multiple_fields(scheme_id, location_id)
return if scheme_id.nil?

2
app/models/user.rb

@ -56,7 +56,7 @@ class User < ApplicationRecord
unassign: "No, unassign the logs",
}.freeze
enum role: ROLES
enum :role, ROLES
scope :search_by_name, ->(name) { where("users.name ILIKE ?", "%#{name}%") }
scope :search_by_email, ->(email) { where("email ILIKE ?", "%#{email}%") }

4
app/models/validations/soft_validations.rb

@ -84,6 +84,8 @@ module Validations::SoftValidations
end
def all_tenants_age_and_gender_information_completed?
return false if hhmemb.present? && hhmemb > 8
person_count = hhmemb || 8
(1..person_count).all? do |n|
@ -235,6 +237,8 @@ private
end
def all_male_tenants_in_the_household?
return false if hhmemb.present? && hhmemb > 8
person_count = hhmemb || 8
(1..person_count).all? do |n|

6
app/services/exports/organisation_export_service.rb

@ -56,11 +56,13 @@ module Exports
def apply_cds_transformation(organisation)
attribute_hash = organisation.attributes
attribute_hash["deleted_at"] = organisation.discarded_at
attribute_hash["deleted_at"] = organisation.discarded_at&.iso8601
attribute_hash["dsa_signed"] = organisation.data_protection_confirmed?
attribute_hash["dsa_signed_at"] = organisation.data_protection_confirmation&.signed_at
attribute_hash["dsa_signed_at"] = organisation.data_protection_confirmation&.signed_at&.iso8601
attribute_hash["dpo_email"] = organisation.data_protection_confirmation&.data_protection_officer_email
attribute_hash["provider_type"] = organisation.provider_type_before_type_cast
attribute_hash["merge_date"] = organisation.merge_date&.iso8601
attribute_hash["available_from"] = organisation.available_from&.iso8601
attribute_hash["profit_status"] = nil # will need update when we add the field to the org
attribute_hash["group"] = nil # will need update when we add the field to the org

1
app/services/exports/user_export_service.rb

@ -60,6 +60,7 @@ module Exports
attribute_hash["organisation_name"] = user.organisation.name
attribute_hash["active"] = user.active?
attribute_hash["phone"] = [user.phone, user.phone_extension].compact.join(" ")
attribute_hash["last_sign_in_at"] = user.last_sign_in_at&.iso8601
attribute_hash
end
end

16
app/services/feature_toggle.rb

@ -11,10 +11,6 @@ class FeatureToggle
!Rails.env.development?
end
def self.duplicate_summary_enabled?
true
end
def self.service_unavailable?
false
end
@ -23,18 +19,6 @@ class FeatureToggle
false
end
def self.delete_scheme_enabled?
true
end
def self.delete_location_enabled?
true
end
def self.delete_user_enabled?
true
end
def self.local_storage?
Rails.env.development?
end

2
app/views/bulk_upload_lettings_logs/forms/prepare_your_file_2024.html.erb

@ -27,8 +27,6 @@
"If you have reordered the headers, keep the headers in the file.",
], type: :bullet %>
<%= govuk_inset_text(text: "You can upload both general needs and supported housing logs in the same file for 2024 to 2025 data.") %>
<h2 class="govuk-heading-s">Save your file</h2>
<%= govuk_list ["Save your file as a CSV.", "Your file should now be ready to upload."], type: :bullet %>

2
app/views/bulk_upload_lettings_resume/deletion_report.html.erb

@ -28,6 +28,6 @@
<div class="govuk-button-group">
<%= form_with model: @form, scope: :form, url: page_bulk_upload_lettings_resume_path(@bulk_upload, "confirm"), method: :patch do |f| %>
<%= f.govuk_submit "Clear this data and upload the logs" %>
<%= govuk_button_link_to "I have fixed these errors and I want to reupload the file", start_bulk_upload_lettings_logs_path, secondary: true %>
<%= govuk_button_link_to "I have fixed these errors and I want to upload the file again", start_bulk_upload_lettings_logs_path, secondary: true %>
<% end %>
</div>

2
app/views/bulk_upload_lettings_soft_validations_check/confirm.html.erb

@ -5,7 +5,7 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<span class="govuk-caption-l">Upload lettings logs in bulk (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">You have chosen to upload all logs from this bulk upload.</h1>
<h1 class="govuk-heading-l">Are you sure you want to upload all logs from this bulk upload?</h1>
<p class="govuk-body"><%= logs_and_soft_validations_warning(@bulk_upload) %></p>

2
app/views/bulk_upload_sales_resume/deletion_report.html.erb

@ -28,6 +28,6 @@
<div class="govuk-button-group">
<%= form_with model: @form, scope: :form, url: page_bulk_upload_sales_resume_path(@bulk_upload, "confirm"), method: :patch do |f| %>
<%= f.govuk_submit "Clear this data and upload the logs" %>
<%= govuk_button_link_to "I have fixed these errors and I want to reupload the file", start_bulk_upload_sales_logs_path, secondary: true %>
<%= govuk_button_link_to "I have fixed these errors and I want to upload the file again", start_bulk_upload_sales_logs_path, secondary: true %>
<% end %>
</div>

2
app/views/bulk_upload_sales_soft_validations_check/confirm.html.erb

@ -5,7 +5,7 @@
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<span class="govuk-caption-l">Upload sales logs in bulk (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">You have chosen to upload all logs from this bulk upload.</h1>
<h1 class="govuk-heading-l">Are you sure you want to upload all logs from this bulk upload?</h1>
<p class="govuk-body"><%= logs_and_soft_validations_warning(@bulk_upload) %></p>

4
app/views/bulk_upload_shared/_moved_user_banner.html.erb

@ -4,9 +4,9 @@
This error report is out of date.
<p>
<% if current_user.id == @bulk_upload.moved_user_id %>
You moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.
You moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.
<% else %>
Some logs in this upload are assigned to <%= @bulk_upload.moved_user_name %>, who has moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.
Some logs in this upload are assigned to <%= @bulk_upload.moved_user_name %>, who has moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.
<% end %>
<% end %>
<% end %>

2
app/views/bulk_upload_shared/guidance.html.erb

@ -75,7 +75,7 @@
<p class="govuk-body">Once you've saved your CSV file, you can upload it via a button at the top of the lettings and sales logs pages.</p>
<p class="govuk-body">When your file is done processing, you will receive an email explaining your next steps. If all your data is valid, your logs will be created. If some data is invalid, you’ll receive an email with instructions about how to resolve the errors.</p>
<p class="govuk-body">If your file has errors on fields 1 through 15 for lettings, or 1 through 18 for sales, you must fix these in the CSV. This is because we need to know these answers to validate the rest of the data. Any errors in these fields will be featured in the error report’s summary tab.</p>
<p class="govuk-body">If none of your errors are in fields 1 through 15 for lettings, or 1 through 18 for sales, you can choose how to fix the errors. You can either fix them in the CSV and reupload, or create partially complete logs and answer the remaining questions on the CORE site. Any errors that affect a significant number of logs will be featured in the error report’s summary tab to help you decide.</p>
<p class="govuk-body">If none of your errors are in fields 1 through 15 for lettings, or 1 through 18 for sales, you can choose how to fix the errors. You can either fix them in the CSV and upload the file again, or create partially complete logs and answer the remaining questions on the CORE site. Any errors that affect a significant number of logs will be featured in the error report’s summary tab to help you decide.</p>
<p class="govuk-body"></p>
<% end %>

2
app/views/devise/sessions/new.html.erb

@ -22,7 +22,7 @@
<%= f.govuk_password_field :password,
autocomplete: "current-password" %>
<%= f.hidden_field :start, value: request["start"] %>
<%= f.hidden_field :start, value: request.params["start"] %>
<%= f.govuk_submit "Sign in" %>
</div>
</div>

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

@ -42,7 +42,7 @@
<% if LocationPolicy.new(current_user, @location).create? %>
<div class="govuk-button-group">
<%= 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? %>
<% if LocationPolicy.new(current_user, @location).delete? %>
<%= delete_location_link(@location) %>
<% end %>
<%= govuk_button_link_to "Cancel", scheme_locations_path(@scheme), secondary: true %>

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

@ -51,6 +51,6 @@
<%= toggle_location_link(@location) %>
<% end %>
<% if LocationPolicy.new(current_user, @location).delete? && FeatureToggle.delete_location_enabled? %>
<% if LocationPolicy.new(current_user, @location).delete? %>
<%= delete_location_link(@location) %>
<% end %>

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

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

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

@ -56,6 +56,6 @@
<%= toggle_scheme_link(@scheme) %>
<% end %>
<% if SchemePolicy.new(current_user, @scheme).delete? && FeatureToggle.delete_scheme_enabled? %>
<% if SchemePolicy.new(current_user, @scheme).delete? %>
<%= delete_scheme_link(@scheme) %>
<% end %>

2
app/views/users/show.html.erb

@ -157,7 +157,7 @@
</span>
<% end %>
<% end %>
<% if UserPolicy.new(current_user, @user).delete? && FeatureToggle.delete_user_enabled? %>
<% if UserPolicy.new(current_user, @user).delete? %>
<%= delete_user_link(@user) %>
<% end %>
</div>

8
bin/rubocop

@ -0,0 +1,8 @@
#!/usr/bin/env ruby
require "rubygems"
require "bundler/setup"
# explicit rubocop config increases performance slightly while avoiding config confusion.
ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__))
load Gem.bin_path("rubocop", "rubocop")

3
bin/setup

@ -1,11 +1,10 @@
#!/usr/bin/env ruby
require "fileutils"
# path to your application root.
APP_ROOT = File.expand_path("..", __dir__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
system(*args, exception: true)
end
FileUtils.chdir APP_ROOT do

13
config/application.rb

@ -12,7 +12,6 @@ require "action_mailbox/engine"
# require "action_text/engine"
require "action_view/railtie"
# require "action_cable/engine"
# require "sprockets/railtie"
# require "rails/test_unit/railtie"
# Require the gems listed in Gemfile, including any gems
@ -22,8 +21,16 @@ Bundler.require(*Rails.groups)
module DataCollector
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.0
config.load_defaults 7.2
# Please, add to the `ignore` list any other `lib` subdirectories that do
# not contain `.rb` files, or that should not be reloaded or eager loaded.
# Common ones are `templates`, `generators`, or `middleware`, for example.
config.autoload_lib(ignore: %w[assets tasks])
# it's strongly discouraged using add_autoload_paths_to_load_path, but rack_attack initializer can't load config files without it
config.add_autoload_paths_to_load_path = true
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
@ -32,6 +39,8 @@ module DataCollector
config.time_zone = "London"
# config.eager_load_paths << Rails.root.join("extras")
# Don't generate system test files.
config.generators.system_tests = nil
config.exceptions_app = routes
config.active_job.queue_adapter = :sidekiq

19
config/environments/development.rb

@ -6,7 +6,7 @@ Rails.application.configure do
# In the development environment your application's code is reloaded any time
# it changes. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
config.enable_reloading = true
# Do not eager load code on boot.
config.eager_load = false
@ -14,7 +14,7 @@ Rails.application.configure do
# Show full error reports.
config.consider_all_requests_local = true
# Enable server timing
# Enable server timing.
config.server_timing = true
# Enable/disable caching. By default caching is disabled.
@ -24,9 +24,7 @@ Rails.application.configure do
config.action_controller.enable_fragment_cache_logging = true
config.cache_store = :memory_store
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{2.days.to_i}",
}
config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" }
else
config.action_controller.perform_caching = false
@ -39,6 +37,8 @@ Rails.application.configure do
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
# Disable caching for Action Mailer templates even if Action Controller
# caching is enabled.
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
@ -72,15 +72,20 @@ Rails.application.configure do
# Highlight code that triggered database queries in logs.
config.active_record.verbose_query_logs = true
# Highlight code that enqueued background job in logs.
config.active_job.verbose_enqueue_logs = true
# Raises error for missing translations.
config.i18n.raise_on_missing_translations = true
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true
# Raise error when a before_action's only/except options reference missing actions.
# config.action_controller.raise_on_missing_callback_actions = true
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
# config.generators.apply_rubocop_autocorrect_after_generate!
Faker::Config.locale = "en-GB"
# see https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017

78
config/environments/production.rb

@ -4,7 +4,7 @@ Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
config.enable_reloading = false
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
@ -13,15 +13,14 @@ Rails.application.configure do
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
# Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
# key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
# Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
@ -34,28 +33,38 @@ Rails.application.configure do
# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local
# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = "wss://example.com/cable"
# config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
# Assume all access to the app is happening through a SSL-terminating reverse proxy.
# Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
# config.assume_ssl = true
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
config.force_ssl = true
# Include generic and useful information about system operation, but avoid logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII).
config.log_level = :info
# Skip http-to-https redirect for the default health check endpoint.
# config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
# Log to STDOUT by default
config.logger = ActiveSupport::Logger.new($stdout)
.tap { |logger| logger.formatter = ::Logger::Formatter.new }
.then { |logger| ActiveSupport::TaggedLogging.new(logger) }
# Prepend all log lines with the following tags.
config.log_tags = [:request_id]
# "info" includes generic and useful information about system operation, but avoids logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII). If you
# want to log everything, set the level to "debug".
config.log_level = :info
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "data_collector_production"
# Disable caching for Action Mailer templates even if Action Controller
# caching is enabled.
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: ENV["APP_HOST"] }
@ -98,37 +107,16 @@ Rails.application.configure do
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
# Inserts middleware to perform automatic connection switching.
# The `database_selector` hash is used to pass options to the DatabaseSelector
# middleware. The `delay` is used to determine how long to wait after a write
# to send a subsequent read to the primary.
#
# The `database_resolver` class is used by the middleware to determine which
# database is appropriate to use based on the time delay.
#
# The `database_resolver_context` class is used by the middleware to set
# timestamps for the last write to the primary. The resolver uses the context
# class timestamps to determine how long to wait before reading from the
# replica.
#
# By default Rails will store a last write timestamp in the session. The
# DatabaseSelector middleware is designed as such you can define your own
# strategy for connection switching and pass that into the middleware through
# these configuration options.
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
# Inserts middleware to perform automatic shard swapping. The `shard_selector` hash
# can be used to pass options to the `ShardSelector` middleware. The `lock` option is
# used to determine whether shard swapping should be prohibited for the request.
#
# The `shard_resolver` option is used by the middleware to determine which shard
# to switch to. The application must provide a mechanism for finding the shard name
# in a proc. See guides for an example.
# config.active_record.shard_selector = { lock: true }
# config.active_record.shard_resolver = ->(request) { Tenant.find_by!(host: request.host).shard }
# Only use :id for inspections in production.
config.active_record.attributes_for_inspect = [:id]
# Enable DNS rebinding protection and other `Host` header attacks.
# config.hosts = [
# "example.com", # Allow requests from example.com
# /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
# ]
# Skip DNS rebinding protection for the default health check endpoint.
# config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
# see https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017
config.active_record.yaml_column_permitted_classes = [Time, BigDecimal]

34
config/environments/test.rb

@ -1,5 +1,4 @@
require "active_support/core_ext/integer/time"
require "faker"
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
@ -9,26 +8,25 @@ require "faker"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Turn false under Spring and add config.action_view.cache_template_loading = true
config.cache_classes = true
# While tests run files are not watched, reloading is not necessary.
config.enable_reloading = false
# Eager loading loads your whole application. When running a single test locally,
# this probably isn't necessary. It's a good idea to do in a continuous integration
# system, or in some way before deploying your code.
# Eager loading loads your entire application. When running a single test locally,
# this is usually not necessary, and can slow down your test suite. However, it's
# recommended that you enable it in continuous integration systems to ensure eager
# loading is working properly before deploying your code.
config.eager_load = ENV["CI"].present?
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=#{1.hour.to_i}",
}
config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{1.hour.to_i}" }
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
config.cache_store = :null_store
# Raise exceptions instead of rendering exception templates.
# Render exception templates for rescuable exceptions and raise for other exceptions.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
@ -37,16 +35,20 @@ Rails.application.configure do
# Store uploaded files on the local file system in a temporary directory.
config.active_storage.service = :test
# Disable caching for Action Mailer templates even if Action Controller
# caching is enabled.
config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
config.action_mailer.default_options = { from: "test@gmail.com" }
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Unlike controllers, the mailer instance doesn't have any context about the
# incoming request so you'll need to provide the :host parameter yourself.
config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
config.action_mailer.default_options = { from: "test@gmail.com" }
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
@ -61,6 +63,10 @@ Rails.application.configure do
# Annotate rendered view with file names.
# config.action_view.annotate_rendered_view_with_filenames = true
# Raise error when a before_action's only/except options reference missing actions.
# config.action_controller.raise_on_missing_callback_actions = true
Faker::Config.locale = "en-GB"
# see https://discuss.rubyonrails.org/t/cve-2022-32224-possible-rce-escalation-bug-with-serialized-columns-in-active-record/81017

6
config/initializers/assets.rb

@ -1 +1,7 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = "1.0"
# Add additional assets to the asset load path.
Rails.application.config.assets.paths << Rails.root.join("node_modules/@fortawesome/fontawesome-free/webfonts")

13
config/initializers/content_security_policy.rb

@ -1,8 +1,8 @@
# Be sure to restart your server when you modify this file.
# Define an application-wide content security policy
# For further information see the following documentation
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
# Define an application-wide content security policy.
# See the Securing Rails Applications Guide for more information:
# https://guides.rubyonrails.org/security.html#content-security-policy-header
# Rails.application.configure do
# config.content_security_policy do |policy|
@ -16,11 +16,10 @@
# # policy.report_uri "/csp-violation-report-endpoint"
# end
#
# # Generate session nonces for permitted importmap and inline scripts
# # Generate session nonces for permitted importmap, inline scripts, and inline styles.
# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
# config.content_security_policy_nonce_directives = %w(script-src)
# config.content_security_policy_nonce_directives = %w(script-src style-src)
#
# # Report CSP violations to a specified URI. See:
# # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only
# # Report violations without enforcing the policy.
# # config.content_security_policy_report_only = true
# end

6
config/initializers/filter_parameter_logging.rb

@ -1,6 +1,8 @@
# Be sure to restart your server when you modify this file.
# Configure sensitive parameters which will be filtered from the log file.
# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
# Use this to limit dissemination of sensitive information.
# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
Rails.application.config.filter_parameters += %i[
passw secret token crypt salt certificate otp ssn reset_password_token
passw secret email secret token _key crypt salt certificate otp ssn reset_password_token
]

20
config/initializers/permissions_policy.rb

@ -1,11 +1,13 @@
# Be sure to restart your server when you modify this file.
# Define an application-wide HTTP permissions policy. For further
# information see https://developers.google.com/web/updates/2018/06/feature-policy
#
# Rails.application.config.permissions_policy do |f|
# f.camera :none
# f.gyroscope :none
# f.microphone :none
# f.usb :none
# f.fullscreen :self
# f.payment :self, "https://secure.example.com"
# information see: https://developers.google.com/web/updates/2018/06/feature-policy
# Rails.application.config.permissions_policy do |policy|
# policy.camera :none
# policy.gyroscope :none
# policy.microphone :none
# policy.usb :none
# policy.fullscreen :self
# policy.payment :self, "https://secure.example.com"
# end

4
config/locales/en.yml

@ -382,6 +382,10 @@ en:
organisation_part_of_another_merge: "This organisation is part of another merge - select a different one."
organisation_part_of_another_incomplete_merge: "Another merge request records %{organisation} as merging into %{absorbing_organisation} on %{merge_date}. Select another organisation or remove this organisation from the other merge request."
organisation_not_selected: "Select an organisation from the search list."
merge_request_id:
blank: "Select a merge request."
merging_organisation_id:
blank: "Select an organisation to merge."
soft_validations:
retirement:

17
config/locales/test.en.yml

@ -0,0 +1,17 @@
en:
forms:
2021:
lettings:
guidance:
what_counts_as_income:
title: "What counts as income?"
content: "What counts as income?"
finding_scheme:
title: "Can’t find your scheme?"
content: "<p>Schemes are attached to the organisation that owns the property. Check you have correctly answered question 1 \"Which organisation owns this property?\"</p>
<p>If your organisation’s schemes were migrated from old CORE, they may have new names and codes. Search by postcode to find your scheme.</p>"
scheme_changes_link_text: "Read more about how schemes have changed"
view_schemes_link_text: "View your organisation’s schemes"
soft_validations:
net_income:
hint_text: "hint text"

4
config/locales/validations/sales/2024/bulk_upload.en.yml

@ -18,8 +18,8 @@ en:
owning_organisation:
not_found: "The owning organisation code is incorrect."
not_stock_owner: "The owning organisation code provided is for an organisation that does not own stock."
not_permitted:
support: "This owning organisation is not affiliated with %(name)."
not_permitted:
support: "This owning organisation is not affiliated with %{name}."
not_support: "You do not have permission to add logs for this owning organisation."
assigned_to:
not_found: "User with the specified email could not be found."

48
config/puma.rb

@ -1,9 +1,25 @@
# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
# This configuration file will be evaluated by Puma. The top-level methods that
# are invoked here are part of Puma's configuration DSL. For more information
# about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
# Puma starts a configurable number of processes (workers) and each process
# serves each request in a thread from an internal thread pool.
#
# The ideal number of threads per worker depends both on how much time the
# application spends waiting for IO operations and on how much you wish to
# to prioritize throughput over latency.
#
# As a rule of thumb, increasing the number of threads will increase how much
# traffic a given process can handle (throughput), but due to CRuby's
# Global VM Lock (GVL) it has diminishing returns and will degrade the
# response time (latency) of the application.
#
# The default is set to 3 threads as it's deemed a decent compromise between
# throughput and latency for the average Rails application.
#
# Any libraries that use a connection pool or another resource pool should
# be configured to provide at least as many connections as the number of
# threads. This includes Active Record's `pool` parameter in `database.yml`.
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
@ -14,30 +30,16 @@ threads min_threads_count, max_threads_count
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the `pidfile` that Puma will use.
# Specify the PID file. Defaults to tmp/pids/server.pid in development.
# In other environments, only set the PID file if requested.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
# workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
# Allow puma to be restarted by `rails restart` command.
# Allow puma to be restarted by `bin/rails restart` command.
plugin :tmp_restart

22
db/migrate/20241206142942_add_service_name_to_active_storage_blobs.active_storage.rb

@ -0,0 +1,22 @@
# This migration comes from active_storage (originally 20190112182829)
class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0]
def up
return unless table_exists?(:active_storage_blobs)
unless column_exists?(:active_storage_blobs, :service_name)
add_column :active_storage_blobs, :service_name, :string
if configured_service = ActiveStorage::Blob.service.name # rubocop:disable Lint/AssignmentInCondition
ActiveStorage::Blob.unscoped.update_all(service_name: configured_service)
end
change_column :active_storage_blobs, :service_name, :string, null: false
end
end
def down
return unless table_exists?(:active_storage_blobs)
remove_column :active_storage_blobs, :service_name
end
end

28
db/migrate/20241206142943_create_active_storage_variant_records.active_storage.rb

@ -0,0 +1,28 @@
# This migration comes from active_storage (originally 20191206030411)
class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0]
def change
return unless table_exists?(:active_storage_blobs)
# Use Active Record's configured type for primary key
create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| # rubocop:disable Rails/CreateTableWithTimestamps
t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type
t.string :variation_digest, null: false
t.index %i[blob_id variation_digest], name: "index_active_storage_variant_records_uniqueness", unique: true
t.foreign_key :active_storage_blobs, column: :blob_id
end
end
private
def primary_key_type
config = Rails.configuration.generators
config.options[config.orm][:primary_key_type] || :primary_key
end
def blobs_primary_key_type
pkey_name = connection.primary_key(:active_storage_blobs)
pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name }
pkey_column.bigint? ? :bigint : pkey_column.type
end
end

8
db/migrate/20241206142944_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb

@ -0,0 +1,8 @@
# This migration comes from active_storage (originally 20211119233751)
class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0]
def change
return unless table_exists?(:active_storage_blobs)
change_column_null(:active_storage_blobs, :checksum, true)
end
end

2
db/schema.rb

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2024_12_04_100518) do
ActiveRecord::Schema[7.2].define(version: 2024_12_06_142944) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

12
db/seeds.rb

@ -12,13 +12,13 @@ def find_or_create_user(organisation, email, name, role)
end
end
unless Rails.env.test?
if LocalAuthority.count.zero?
la_path = "config/local_authorities_data/initial_local_authorities.csv"
service = Imports::LocalAuthoritiesService.new(path: la_path)
service.call
end
if LocalAuthority.count.zero?
la_path = "config/local_authorities_data/initial_local_authorities.csv"
service = Imports::LocalAuthoritiesService.new(path: la_path)
service.call
end
unless Rails.env.test?
if LaRentRange.count.zero?
Dir.glob("config/rent_range_data/*.csv").each do |path|
start_year = File.basename(path, ".csv")

2
package.json

@ -24,7 +24,7 @@
"html5shiv": "^3.7.3",
"intersection-observer": "^0.12.0",
"mini-css-extract-plugin": "^2.6.0",
"rails_admin": "3.1.3",
"rails_admin": "3.3.0",
"regenerator-runtime": "^0.13.9",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",

2
spec/controllers/errors_controller_spec.rb

@ -18,7 +18,7 @@ RSpec.describe ErrorsController, type: :controller do
describe "GET #unprocessable_entity" do
it "returns unprocessable_entity" do
get :unprocessable_entity
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
end
end
end

6
spec/features/organisation_spec.rb

@ -206,14 +206,14 @@ RSpec.describe "User Features" do
it "can filter lettings logs by year" do
check("years-2022-field")
click_button("Apply filters")
expect(page).to have_current_path("/organisations/#{org_id}/lettings-logs?years[]=&years[]=2022&status[]=&needstypes[]=&assigned_to=all&user_text_search=&user=&owning_organisation_select=all&owning_organisation_text_search=&owning_organisation=&managing_organisation_select=all&managing_organisation_text_search=&managing_organisation=")
expect(page).to have_current_path("/organisations/#{org_id}/lettings-logs?%5Byears%5D[]=&years[]=2022&%5Bstatus%5D[]=&%5Bneedstypes%5D[]=&assigned_to=all&user_text_search=&user=&owning_organisation_select=all&owning_organisation_text_search=&owning_organisation=&managing_organisation_select=all&managing_organisation_text_search=&managing_organisation=")
expect(page).not_to have_link first_log.id.to_s, href: "/lettings-logs/#{first_log.id}"
end
it "can filter lettings logs by needstype" do
check("needstypes-1-field")
click_button("Apply filters")
expect(page).to have_current_path("/organisations/#{org_id}/lettings-logs?years[]=&status[]=&needstypes[]=&needstypes[]=1&assigned_to=all&user_text_search=&user=&owning_organisation_select=all&owning_organisation_text_search=&owning_organisation=&managing_organisation_select=all&managing_organisation_text_search=&managing_organisation=")
expect(page).to have_current_path("/organisations/#{org_id}/lettings-logs?%5Byears%5D[]=&%5Bstatus%5D[]=&%5Bneedstypes%5D[]=&needstypes[]=1&assigned_to=all&user_text_search=&user=&owning_organisation_select=all&owning_organisation_text_search=&owning_organisation=&managing_organisation_select=all&managing_organisation_text_search=&managing_organisation=")
other_general_needs_logs.each do |general_needs_log|
expect(page).to have_link general_needs_log.id.to_s, href: "/lettings-logs/#{general_needs_log.id}"
end
@ -256,7 +256,7 @@ RSpec.describe "User Features" do
end
check("years-2022-field")
click_button("Apply filters")
expect(page).to have_current_path("/organisations/#{org_id}/sales-logs?years[]=&years[]=2022&status[]=&assigned_to=all&user_text_search=&user=&owning_organisation_select=all&owning_organisation_text_search=&owning_organisation=&managing_organisation_select=all&managing_organisation_text_search=&managing_organisation=")
expect(page).to have_current_path("/organisations/#{org_id}/sales-logs?%5Byears%5D[]=&years[]=2022&%5Bstatus%5D[]=&assigned_to=all&user_text_search=&user=&owning_organisation_select=all&owning_organisation_text_search=&owning_organisation=&managing_organisation_select=all&managing_organisation_text_search=&managing_organisation=")
expect(page).not_to have_link first_log.id.to_s, href: "/sales-logs/#{first_log.id}"
end
end

4
spec/features/schemes_spec.rb

@ -87,7 +87,7 @@ RSpec.describe "Schemes scheme Features" do
it "displays the filters component with a correct count and clear button" do
expect(page).to have_content("2 filters applied")
expect(page).to have_link("Clear", href: /clear-filters\?filter_type=schemes/)
expect(page).to have_link("Clear", href: /clear-filters\?.*filter_type=schemes/)
end
context "when clearing the filters" do
@ -326,7 +326,7 @@ RSpec.describe "Schemes scheme Features" do
it "displays the filters component with a correct count and clear button" do
expect(page).to have_content("2 filters applied")
expect(page).to have_link("Clear", href: /\/clear-filters\?filter_type=scheme_locations/)
expect(page).to have_link("Clear", href: /\/clear-filters\?.*filter_type=scheme_locations/)
end
context "when clearing the filters" do

6
spec/features/user_spec.rb

@ -269,7 +269,7 @@ RSpec.describe "User Features" do
it "displays the filters component with a correct count and clear button" do
expect(page).to have_content("2 filters applied")
expect(page).to have_link("Clear", href: /clear-filters\?filter_type=users/)
expect(page).to have_link("Clear", href: /clear-filters\?.*filter_type=users/)
end
context "when clearing the filters" do
@ -678,7 +678,7 @@ RSpec.describe "User Features" do
fill_in("code", with: otp)
click_button("Submit")
expect(page).to have_content("Check your email")
expect(page).to have_http_status(:unprocessable_entity)
expect(page).to have_http_status(:unprocessable_content)
expect(page).to have_title("Error")
expect(page).to have_selector(".govuk-error-summary__title")
end
@ -691,7 +691,7 @@ RSpec.describe "User Features" do
fill_in("code", with: otp)
click_button("Submit")
expect(page).to have_content("Check your email")
expect(page).to have_http_status(:unprocessable_entity)
expect(page).to have_http_status(:unprocessable_content)
expect(page).to have_title("Error")
expect(page).to have_selector(".govuk-error-summary__title")
end

2
spec/fixtures/exports/user.xml vendored

@ -6,7 +6,7 @@
<name>Danny Rojas</name>
<organisation_id>{organisation_id}</organisation_id>
<sign_in_count>5</sign_in_count>
<last_sign_in_at/>
<last_sign_in_at>2022-03-03T00:00:00+00:00</last_sign_in_at>
<role>data_provider</role>
<phone>1234512345123 123</phone>
<is_dpo>false</is_dpo>

28
spec/models/validations/soft_validations_spec.rb

@ -174,6 +174,20 @@ RSpec.describe Validations::SoftValidations do
end
end
context "when all tenants are male and household members are over 8" do
it "does not show the interruption screen" do
(1..8).each do |n|
record.send("sex#{n}=", "M")
record.send("age#{n}=", 30)
record.send("age#{n}_known=", 0)
record.send("details_known_#{n}=", 0) unless n == 1
end
record.preg_occ = 1
record.hhmemb = 9
expect(record.all_male_tenants_in_a_pregnant_household?).to be false
end
end
context "when female tenants are under 16" do
it "shows the interruption screen" do
record.age2 = 14
@ -219,6 +233,20 @@ RSpec.describe Validations::SoftValidations do
expect(record.female_in_pregnant_household_in_soft_validation_range?).to be false
end
end
context "when number of household members is over 8" do
it "does not show the interruption screen" do
(1..8).each do |n|
record.send("sex#{n}=", "F")
record.send("age#{n}=", 50)
record.send("age#{n}_known=", 0)
record.send("details_known_#{n}=", 0) unless n == 1
end
record.preg_occ = 1
record.hhmemb = 9
expect(record.female_in_pregnant_household_in_soft_validation_range?).to be false
end
end
end
describe "major repairs date soft validations" do

2
spec/rails_helper.rb

@ -51,7 +51,7 @@ rescue ActiveRecord::PendingMigrationError => e
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.fixture_paths = ["#{::Rails.root}/spec/fixtures"]
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false

2
spec/requests/auth/passwords_controller_spec.rb

@ -107,7 +107,7 @@ RSpec.describe Auth::PasswordsController, type: :request do
it "shows an error on the same page" do
put "/account/password", headers: headers, params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_css("h1", text: "Reset your password")
expect(page).to have_content("passwords you entered do not match")
end

8
spec/requests/bulk_upload_lettings_results_controller_spec.rb

@ -68,7 +68,7 @@ RSpec.describe BulkUploadLettingsResultsController, type: :request do
get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(CGI.unescapeHTML(response.body)).to include("Some logs in this upload are assigned to #{user.name}, who has moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(CGI.unescapeHTML(response.body)).to include("Some logs in this upload are assigned to #{user.name}, who has moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
@ -79,7 +79,7 @@ RSpec.describe BulkUploadLettingsResultsController, type: :request do
get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
end
@ -138,7 +138,7 @@ RSpec.describe BulkUploadLettingsResultsController, type: :request do
get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("Some logs in this upload are assigned to #{other_user.name}, who has moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("Some logs in this upload are assigned to #{other_user.name}, who has moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
@ -149,7 +149,7 @@ RSpec.describe BulkUploadLettingsResultsController, type: :request do
get "/lettings-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
end

2
spec/requests/bulk_upload_lettings_soft_validations_check_controller_spec.rb

@ -98,7 +98,7 @@ RSpec.describe BulkUploadLettingsSoftValidationsCheckController, type: :request
expect(response).to be_successful
expect(response.body).to include("You have chosen to upload all logs from this bulk upload.")
expect(response.body).to include("Are you sure you want to upload all logs from this bulk upload?")
expect(response.body).to include("You will upload 2 logs. There are unexpected answers in 2 logs, and 2 unexpected answers in total. These unexpected answers will be marked as correct.")
expect(response.body).not_to include("You’ve successfully uploaded")
end

8
spec/requests/bulk_upload_sales_results_controller_spec.rb

@ -30,7 +30,7 @@ RSpec.describe BulkUploadSalesResultsController, type: :request do
get "/sales-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("Some logs in this upload are assigned to #{user.name}, who has moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("Some logs in this upload are assigned to #{user.name}, who has moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
@ -41,7 +41,7 @@ RSpec.describe BulkUploadSalesResultsController, type: :request do
get "/sales-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
end
@ -113,7 +113,7 @@ RSpec.describe BulkUploadSalesResultsController, type: :request do
get "/sales-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("Some logs in this upload are assigned to #{other_user.name}, who has moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("Some logs in this upload are assigned to #{other_user.name}, who has moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
@ -124,7 +124,7 @@ RSpec.describe BulkUploadSalesResultsController, type: :request do
get "/sales-logs/bulk-upload-results/#{bulk_upload.id}/summary"
expect(response.body).to include("This error report is out of date.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Reupload the file to get an accurate error report.")
expect(response.body).to include("You moved to a different organisation since this file was uploaded. Upload the file again to get an accurate error report.")
end
end
end

2
spec/requests/bulk_upload_sales_soft_validations_check_controller_spec.rb

@ -98,7 +98,7 @@ RSpec.describe BulkUploadSalesSoftValidationsCheckController, type: :request do
expect(response).to be_successful
expect(response.body).to include("You have chosen to upload all logs from this bulk upload.")
expect(response.body).to include("Are you sure you want to upload all logs from this bulk upload?")
expect(response.body).to include("You will upload 2 logs. There are unexpected answers in 2 logs, and 2 unexpected answers in total. These unexpected answers will be marked as correct.")
expect(response.body).not_to include("You’ve successfully uploaded")
end

32
spec/requests/delete_logs_controller_spec.rb

@ -61,8 +61,9 @@ RSpec.describe "DeleteLogs", type: :request do
allow(FilterManager).to receive(:filter_logs).and_return LettingsLog.all
end
it "throws an error if selected ids are not provided" do
expect { post delete_logs_lettings_logs_path }.to raise_error ActionController::ParameterMissing
it "returns bad request if selected ids are not provided" do
post delete_logs_lettings_logs_path
expect(response).to have_http_status(:bad_request)
end
it "calls the filter service with the filters in the session and the search term from the query params" do
@ -120,7 +121,8 @@ RSpec.describe "DeleteLogs", type: :request do
end
it "requires delete logs form data to be provided" do
expect { post delete_logs_confirmation_lettings_logs_path }.to raise_error(ActionController::ParameterMissing)
post delete_logs_confirmation_lettings_logs_path
expect(response).to have_http_status(:bad_request)
end
it "shows the correct title" do
@ -346,8 +348,9 @@ RSpec.describe "DeleteLogs", type: :request do
allow(FilterManager).to receive(:filter_logs).and_return SalesLog.all
end
it "throws an error if selected ids are not provided" do
expect { post delete_logs_sales_logs_path }.to raise_error ActionController::ParameterMissing
it "returns bad request if selected ids are not provided" do
post delete_logs_sales_logs_path
expect(response).to have_http_status(:bad_request)
end
it "calls the filter service with the filters in the session and the search term from the query params" do
@ -405,7 +408,8 @@ RSpec.describe "DeleteLogs", type: :request do
end
it "requires delete logs form data to be provided" do
expect { post delete_logs_confirmation_sales_logs_path }.to raise_error(ActionController::ParameterMissing)
post delete_logs_confirmation_sales_logs_path
expect(response).to have_http_status(:bad_request)
end
it "shows the correct title" do
@ -635,8 +639,9 @@ RSpec.describe "DeleteLogs", type: :request do
allow(FilterManager).to receive(:filter_logs).and_return LettingsLog.all
end
it "throws an error if selected ids are not provided" do
expect { post delete_lettings_logs_organisation_path(id: organisation) }.to raise_error ActionController::ParameterMissing
it "returns bad request if selected ids are not provided" do
post delete_lettings_logs_organisation_path(id: organisation)
expect(response).to have_http_status(:bad_request)
end
it "calls the filter service with the filters in the session and the search term from the query params" do
@ -694,7 +699,8 @@ RSpec.describe "DeleteLogs", type: :request do
end
it "requires delete logs form data to be provided" do
expect { post delete_lettings_logs_confirmation_organisation_path(id: organisation) }.to raise_error(ActionController::ParameterMissing)
post delete_lettings_logs_confirmation_organisation_path(id: organisation)
expect(response).to have_http_status(:bad_request)
end
it "shows the correct title" do
@ -858,8 +864,9 @@ RSpec.describe "DeleteLogs", type: :request do
allow(FilterManager).to receive(:filter_logs).and_return SalesLog.all
end
it "throws an error if selected ids are not provided" do
expect { post delete_sales_logs_organisation_path(id: organisation) }.to raise_error ActionController::ParameterMissing
it "returns bad request if selected ids are not provided" do
post delete_sales_logs_organisation_path(id: organisation)
expect(response).to have_http_status(:bad_request)
end
it "calls the filter service with the filters in the session and the search term from the query params" do
@ -917,7 +924,8 @@ RSpec.describe "DeleteLogs", type: :request do
end
it "requires delete logs form data to be provided" do
expect { post delete_sales_logs_confirmation_organisation_path(id: organisation) }.to raise_error(ActionController::ParameterMissing)
post delete_sales_logs_confirmation_organisation_path
expect(response).to have_http_status(:bad_request)
end
it "shows the correct title" do

2
spec/requests/form_controller_spec.rb

@ -1159,7 +1159,6 @@ RSpec.describe FormController, type: :request do
it "displays a success banner" do
follow_redirect!
follow_redirect!
expect(response.body).to include("You have successfully updated Q31: lead tenant’s age")
end
@ -1182,7 +1181,6 @@ RSpec.describe FormController, type: :request do
end
it "displays a success banner without crashing" do
follow_redirect!
follow_redirect!
expect(response.body).to include("You have successfully updated")
end

8
spec/requests/lettings_logs_controller_spec.rb

@ -81,7 +81,7 @@ RSpec.describe LettingsLogsController, type: :request do
it "validates lettings log parameters" do
json_response = JSON.parse(response.body)
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(json_response["errors"]).to match_array([["offered", [I18n.t("validations.shared.numeric.within_range", field: "Times previously offered since becoming available", min: 0, max: 20)]], ["age1", [I18n.t("validations.shared.numeric.within_range", field: "Lead tenant’s age", min: 16, max: 120)]]])
end
end
@ -609,7 +609,7 @@ RSpec.describe LettingsLogsController, type: :request do
it "displays filter" do
get "/lettings-logs?bulk_upload_id[]=#{bulk_upload.id}"
expect(page).to have_content("With logs from bulk upload")
expect(page).to have_content("Only logs from this bulk upload")
end
it "hides collection year filter" do
@ -695,7 +695,7 @@ RSpec.describe LettingsLogsController, type: :request do
context "without bulk_upload_id" do
it "does not display filter" do
get "/lettings-logs"
expect(page).not_to have_content("With logs from bulk upload")
expect(page).not_to have_content("Only logs from this bulk upload")
end
it "displays button to create a new log" do
@ -1612,7 +1612,7 @@ RSpec.describe LettingsLogsController, type: :request do
let(:params) { { age1: 200 } }
it "returns 422" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
end
it "returns an error message" do

32
spec/requests/locations_controller_spec.rb

@ -1192,7 +1192,7 @@ RSpec.describe LocationsController, type: :request do
end
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.startdate_invalid"))
end
end
@ -1266,7 +1266,7 @@ RSpec.describe LocationsController, type: :request do
end
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.startdate_invalid"))
end
end
@ -1702,7 +1702,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { "deactivation_date": "" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.not_selected"))
end
end
@ -1711,7 +1711,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -1720,7 +1720,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.out_of_range", date: "1 April 2022"))
end
end
@ -1729,7 +1729,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -1738,7 +1738,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -1747,7 +1747,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -1758,7 +1758,7 @@ RSpec.describe LocationsController, type: :request do
let(:add_deactivations) { create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 10, 12), location:) }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.deactivation.during_deactivated_period"))
end
end
@ -2110,7 +2110,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { "reactivation_date": "" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.not_selected"))
end
end
@ -2119,7 +2119,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "44", "reactivation_date(1i)": "2022" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -2128,7 +2128,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "4", "reactivation_date(1i)": "2020" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.out_of_range", date: "1 April 2022"))
end
end
@ -2137,7 +2137,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "", "reactivation_date(2i)": "2", "reactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -2146,7 +2146,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "", "reactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -2155,7 +2155,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "2", "reactivation_date(1i)": "" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.toggle_date.invalid"))
end
end
@ -2165,7 +2165,7 @@ RSpec.describe LocationsController, type: :request do
let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "8", "reactivation_date(2i)": "9", "reactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.location.reactivation.before_deactivation", date: "10 October 2022"))
end
end

20
spec/requests/merge_requests_controller_spec.rb

@ -95,7 +95,7 @@ RSpec.describe MergeRequestsController, type: :request do
end
it "displays the page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Another merge request records #{another_organisation.name} as merging into #{other_merge_request.absorbing_organisation&.name} on 4 May 2022. Select another organisation or remove this organisation from the other merge request.")
end
end
@ -113,7 +113,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "does not update the merge request" do
merge_request.reload
expect(merge_request.merging_organisations.count).to eq(0)
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.merge_request.organisation_part_of_another_merge"))
end
end
@ -159,7 +159,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "does not update the merge request" do
merge_request.reload
expect(merge_request.merging_organisations.count).to eq(0)
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.merge_request.organisation_not_selected"))
end
end
@ -174,7 +174,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "does not update the merge request" do
merge_request.reload
expect(merge_request.merging_organisations.count).to eq(0)
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.merge_request.organisation_not_selected"))
end
end
@ -363,7 +363,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "renders the error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Enter a merge date")
end
@ -385,7 +385,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "displays the page with an error message" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Enter a valid merge date")
end
end
@ -426,7 +426,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "displays the page with an error message" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("The merge date must not be later than a year from today’s date.")
end
end
@ -467,7 +467,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "renders the error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("You must answer absorbing organisation already active?")
end
@ -490,7 +490,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "renders the error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("You must answer was this merge reported by a helpdesk ticket?")
end
@ -511,7 +511,7 @@ RSpec.describe MergeRequestsController, type: :request do
it "renders the error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("You must answer the ticket number")
end

2
spec/requests/notifications_controller_spec.rb

@ -37,7 +37,7 @@ RSpec.describe NotificationsController, type: :request do
it "gives an error response" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
end
end

6
spec/requests/organisations_controller_spec.rb

@ -1889,7 +1889,7 @@ RSpec.describe OrganisationsController, type: :request do
it "displays the form with an error message" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.organisation.name_missing"))
expect(page).to have_content(I18n.t("validations.organisation.provider_type_missing"))
end
@ -2055,7 +2055,7 @@ RSpec.describe OrganisationsController, type: :request do
end
it "has clear filters link" do
expect(page).to have_link("Clear", href: clear_filters_path(filter_type: "lettings_logs", path_params: { organisation_id: organisation.id }))
expect(page).to have_link("Clear", href: clear_filters_path(filter_type: "lettings_logs", filter_path_params: { organisation_id: organisation.id }))
end
end
end
@ -2417,7 +2417,7 @@ RSpec.describe OrganisationsController, type: :request do
it "displays an error" do
post "/organisations/#{organisation.id}/schemes/duplicates", headers: headers, params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("You must resolve all duplicates or indicate that there are no duplicates")
end
end

6
spec/requests/sales_logs_controller_spec.rb

@ -92,7 +92,7 @@ RSpec.describe SalesLogsController, type: :request do
it "validates sales log parameters" do
json_response = JSON.parse(response.body)
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(json_response["errors"]).to match_array([["beds", ["Number of bedrooms must be 1 if the property is a bedsit."]], ["proptype", ["Answer cannot be 'Bedsit' if the property has 2 or more bedrooms."]]])
end
end
@ -452,7 +452,7 @@ RSpec.describe SalesLogsController, type: :request do
it "displays filter" do
get "/sales-logs?bulk_upload_id[]=#{bulk_upload.id}"
expect(page).to have_content("With logs from bulk upload")
expect(page).to have_content("Only logs from this bulk upload")
end
it "hides collection year filter" do
@ -536,7 +536,7 @@ RSpec.describe SalesLogsController, type: :request do
context "without bulk_upload_id" do
it "does not display filter" do
get "/sales-logs"
expect(page).not_to have_content("With logs from bulk upload")
expect(page).not_to have_content("Only logs from this bulk upload")
end
it "displays button to create a new log" do

28
spec/requests/schemes_controller_spec.rb

@ -1057,7 +1057,7 @@ RSpec.describe SchemesController, type: :request do
it "renders the same page with error message" do
post "/schemes", params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Create a new supported housing scheme")
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.scheme_type.invalid"))
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.registered_under_care_act.invalid"))
@ -1185,7 +1185,7 @@ RSpec.describe SchemesController, type: :request do
it "renders the same page with error message" do
post "/schemes", params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Create a new supported housing scheme")
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.scheme_type.invalid"))
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.registered_under_care_act.invalid"))
@ -1318,7 +1318,7 @@ RSpec.describe SchemesController, type: :request do
it "renders the same page with error message" do
post "/schemes", params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Create a new supported housing scheme")
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.scheme_type.invalid"))
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.registered_under_care_act.invalid"))
@ -1334,7 +1334,7 @@ RSpec.describe SchemesController, type: :request do
it "displays the new page with an error message" do
post "/schemes", params: params
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Enter an organisation that owns housing stock")
end
end
@ -1375,7 +1375,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme: { owning_organisation_id: user.organisation.id, arrangement_type: nil, confirmed: true, page: "check-answers" } } }
it "does not allow the scheme to be confirmed" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.arrangement_type.invalid"))
end
end
@ -1417,7 +1417,7 @@ RSpec.describe SchemesController, type: :request do
end
it "renders the same page with error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Create a new supported housing scheme")
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.service_name.invalid"))
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.scheme_type.invalid"))
@ -1684,7 +1684,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme: { owning_organisation_id: user.organisation.id, arrangement_type: nil, confirmed: true, page: "check-answers" } } }
it "does not allow the scheme to be confirmed" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.arrangement_type.invalid"))
end
end
@ -1728,7 +1728,7 @@ RSpec.describe SchemesController, type: :request do
end
it "renders the same page with error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Create a new supported housing scheme")
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.owning_organisation_id.invalid"))
expect(page).to have_content(I18n.t("activerecord.errors.models.scheme.attributes.service_name.invalid"))
@ -2895,7 +2895,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme_deactivation_period: { "deactivation_date": "" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.scheme.toggle_date.not_selected"))
end
end
@ -2904,7 +2904,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.scheme.toggle_date.invalid"))
end
end
@ -2913,7 +2913,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } }
it "displays the new page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.scheme.toggle_date.out_of_range", date: "1 April 2022"))
end
end
@ -2922,7 +2922,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.scheme.toggle_date.invalid"))
end
end
@ -2931,7 +2931,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.scheme.toggle_date.invalid"))
end
end
@ -2940,7 +2940,7 @@ RSpec.describe SchemesController, type: :request do
let(:params) { { scheme_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } }
it "displays page with an error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.scheme.toggle_date.invalid"))
end
end

58
spec/requests/users_controller_spec.rb

@ -67,7 +67,7 @@ RSpec.describe UsersController, type: :request do
end
it "shows an error on the same page if passwords don't match" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_css("h1", class: "govuk-heading-l", text: "Change your password")
expect(page).to have_selector(".govuk-error-summary__title")
expect(page).to have_content("passwords you entered do not match")
@ -349,7 +349,7 @@ RSpec.describe UsersController, type: :request do
end
it "show an error" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
end
end
@ -377,7 +377,7 @@ RSpec.describe UsersController, type: :request do
end
it "shows an error if passwords don't match" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_selector(".govuk-error-summary__title")
end
end
@ -792,9 +792,8 @@ RSpec.describe UsersController, type: :request do
context "when the current user does not match the user ID" do
it "there is no route" do
expect {
get "/users/#{other_user.id}/password/edit", headers:, params: {}
}.to raise_error(ActionController::RoutingError)
get "/users/#{other_user.id}/password/edit", headers:, params: {}
expect(response).to have_http_status(:not_found)
end
end
end
@ -840,7 +839,7 @@ RSpec.describe UsersController, type: :request do
end
it "shows an error if passwords don't match" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_selector(".govuk-error-summary__title")
end
end
@ -955,7 +954,7 @@ RSpec.describe UsersController, type: :request do
end
it "show an error" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
end
end
@ -976,7 +975,7 @@ RSpec.describe UsersController, type: :request do
let(:phone) { "" }
it "validates telephone number" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.phone.blank"))
end
end
@ -985,7 +984,7 @@ RSpec.describe UsersController, type: :request do
let(:phone) { "randomstring" }
it "validates telephone number" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.phone.invalid"))
end
end
@ -994,7 +993,7 @@ RSpec.describe UsersController, type: :request do
let(:phone) { "123" }
it "validates telephone number" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.phone.invalid"))
end
end
@ -1075,7 +1074,7 @@ RSpec.describe UsersController, type: :request do
it "shows an error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.email.taken"))
end
end
@ -1093,7 +1092,7 @@ RSpec.describe UsersController, type: :request do
it "shows an error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("validations.role.invalid"))
end
end
@ -1111,7 +1110,7 @@ RSpec.describe UsersController, type: :request do
it "shows an error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.name.blank"))
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.email.blank"))
end
@ -1131,7 +1130,7 @@ RSpec.describe UsersController, type: :request do
it "validates telephone number" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.phone.invalid"))
end
end
@ -1141,7 +1140,7 @@ RSpec.describe UsersController, type: :request do
it "validates telephone number" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.phone.invalid"))
end
end
@ -1748,9 +1747,8 @@ RSpec.describe UsersController, type: :request do
context "when the current user does not match the user ID" do
it "there is no route" do
expect {
get "/users/#{other_user.id}/password/edit", headers:, params: {}
}.to raise_error(ActionController::RoutingError)
get "/users/#{other_user.id}/password/edit", headers:, params: {}
expect(response).to have_http_status(:not_found)
end
end
end
@ -1912,7 +1910,7 @@ RSpec.describe UsersController, type: :request do
end
it "shows an error if passwords don't match" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_selector(".govuk-error-summary__title")
end
end
@ -1928,7 +1926,7 @@ RSpec.describe UsersController, type: :request do
let(:params) { { id: user.id, user: { organisation_id: "" } } }
it "does not update the organisation" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_selector(".govuk-error-summary__title")
end
end
@ -2097,7 +2095,7 @@ RSpec.describe UsersController, type: :request do
let(:params) { { id: other_user.id, user: { organisation_id: "" } } }
it "does not update the organisation" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_selector(".govuk-error-summary__title")
end
end
@ -2136,7 +2134,7 @@ RSpec.describe UsersController, type: :request do
end
it "displays the error message" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("Select if you want to reassign logs")
end
end
@ -2184,7 +2182,7 @@ RSpec.describe UsersController, type: :request do
end
it "required the new org to have stock owner relationship with the current user org" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("New org must be a stock owner of #{other_user.organisation_name} to make this change.")
end
end
@ -2198,7 +2196,7 @@ RSpec.describe UsersController, type: :request do
end
it "required the new org to have stock owner relationship with the managing organisations" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("New org must be a stock owner of #{other_user.organisation_name}, #{new_organisation_2.name}, and #{new_organisation_3.name} to make this change.")
end
end
@ -2215,7 +2213,7 @@ RSpec.describe UsersController, type: :request do
end
it "required the new org to have managing agent relationship with the current user org" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("New org must be a managing agent of #{other_user.organisation_name} to make this change.")
end
end
@ -2229,7 +2227,7 @@ RSpec.describe UsersController, type: :request do
end
it "required the new org to have managing agent relationship with owning organisations" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content("New org must be a managing agent of #{other_user.organisation.name}, #{new_organisation_2.name}, and #{new_organisation_3.name} to make this change.")
end
end
@ -2246,7 +2244,7 @@ RSpec.describe UsersController, type: :request do
end
it "show an error" do
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
end
end
end
@ -2309,7 +2307,7 @@ RSpec.describe UsersController, type: :request do
it "shows an error messages for all failed validations" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.name.blank"))
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.email.blank"))
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.organisation_id.blank"))
@ -2324,7 +2322,7 @@ RSpec.describe UsersController, type: :request do
it "shows an error" do
request
expect(response).to have_http_status(:unprocessable_entity)
expect(response).to have_http_status(:unprocessable_content)
expect(page).to have_content(I18n.t("activerecord.errors.models.user.attributes.email.taken"))
end
end

2
spec/services/exports/organisation_export_service_spec.rb

@ -17,7 +17,7 @@ RSpec.describe Exports::OrganisationExportService do
def replace_entity_ids(organisation, export_template)
export_template.sub!(/\{id\}/, organisation["id"].to_s)
export_template.sub!(/\{name\}/, organisation["name"])
export_template.sub!(/\{dsa_signed_at\}/, organisation.data_protection_confirmation&.signed_at.to_s)
export_template.sub!(/\{dsa_signed_at\}/, organisation.data_protection_confirmation&.signed_at&.iso8601)
export_template.sub!(/\{dpo_email\}/, organisation.data_protection_confirmation&.data_protection_officer_email)
end

2
spec/services/exports/user_export_service_spec.rb

@ -43,7 +43,7 @@ RSpec.describe Exports::UserExportService do
end
context "and one user is available for export" do
let!(:user) { create(:user, organisation:, name: "Danny Rojas", phone_extension: "123") }
let!(:user) { create(:user, organisation:, name: "Danny Rojas", phone_extension: "123", last_sign_in_at: Time.zone.local(2022, 3, 3)) }
it "generates a ZIP export file with the expected filename" do
expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args)

70
spec/services/merge/merge_organisations_service_spec.rb

@ -16,7 +16,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "when merging a single organisation into an existing organisation" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: nil) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: nil) }
let(:absorbing_organisation) { create(:organisation, holds_own_stock: false, name: "absorbing org") }
let(:absorbing_organisation_user) { create(:user, organisation: absorbing_organisation) }
@ -53,7 +53,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -97,7 +97,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -134,7 +134,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -327,7 +327,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and deactivation is after the merge date and before an open collection window" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.today - 6.years) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.today - 6.years) }
let!(:scheme) { create(:scheme, owning_organisation: merging_organisation, old_id: "scheme_old_id", old_visible_id: "scheme_old_visible_id", startdate: nil) }
let!(:location) { create(:location, scheme:, old_id: "location_old_id", old_visible_id: "location_old_visible_id", startdate: nil) }
@ -551,7 +551,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -584,7 +584,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -596,7 +596,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "with merge date in closed collection year" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.local(2021, 3, 3)) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.local(2021, 3, 3)) }
it "does not validate saledate for closed collection years" do
sales_log.saledate = Time.zone.local(2022, 5, 1)
@ -611,7 +611,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and merge date is provided" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.yesterday) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.yesterday) }
it "sets merge date on merged organisation" do
merge_organisations_service.call
@ -646,7 +646,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -682,7 +682,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -706,7 +706,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "with merge date in closed collection year" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.local(2021, 3, 3)) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.local(2021, 3, 3)) }
it "does not validate startdate for closed collection years" do
owned_lettings_log.startdate = Time.zone.local(2022, 4, 1)
@ -825,7 +825,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -842,7 +842,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and absorbing_organisation_active_from_merge_date is true" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.yesterday, absorbing_organisation_active_from_merge_date: true) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.yesterday, absorbing_organisation_active_from_merge_date: true) }
it "sets available from to merge_date for absorbing organisation" do
merge_organisations_service.call
@ -854,7 +854,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and absorbing_organisation_active_from_merge_date is true" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], absorbing_organisation_active_from_merge_date: true) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, absorbing_organisation_active_from_merge_date: true) }
it "sets available from to merge_date (today) for absorbing organisation" do
merge_organisations_service.call
@ -910,7 +910,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "when merging a multiple organisations into an existing organisation" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: nil) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: nil) }
let(:absorbing_organisation) { create(:organisation, holds_own_stock: false, name: "absorbing org") }
let(:absorbing_organisation_user) { create(:user, organisation: absorbing_organisation) }
@ -944,7 +944,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1069,7 +1069,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(absorbing_organisation.id).and_return(absorbing_organisation)
allow(absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1086,7 +1086,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and merge date is provided" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.yesterday) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.yesterday) }
it "sets merge date and absorbing organisation on merged organisations" do
merge_organisations_service.call
@ -1102,7 +1102,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "when merging a single organisation into a new organisation" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: nil) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids:, merge_date: nil) }
let(:new_absorbing_organisation) { create(:organisation, :without_dpc, holds_own_stock: false) }
let(:new_absorbing_organisation_user) { create(:user, organisation: new_absorbing_organisation) }
@ -1139,7 +1139,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1183,7 +1183,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1220,7 +1220,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1325,7 +1325,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1357,7 +1357,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1370,7 +1370,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and merge date is provided" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.yesterday) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.yesterday) }
it "sets merge date on merged organisation" do
merge_organisations_service.call
@ -1396,7 +1396,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1432,7 +1432,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1538,7 +1538,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1555,7 +1555,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and absorbing_organisation_active_from_merge_date is true" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.yesterday, absorbing_organisation_active_from_merge_date: true) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.yesterday, absorbing_organisation_active_from_merge_date: true) }
it "sets available from to merge_date for absorbing organisation" do
merge_organisations_service.call
@ -1567,7 +1567,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and absorbing_organisation_active_from_merge_date is true" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], absorbing_organisation_active_from_merge_date: true) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids:, absorbing_organisation_active_from_merge_date: true) }
it "sets available from to merge_date (today) for absorbing organisation" do
merge_organisations_service.call
@ -1579,7 +1579,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "when merging multiple organisations into a new organisation" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: nil) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids:, merge_date: nil) }
let(:new_absorbing_organisation) { create(:organisation, :without_dpc, holds_own_stock: false) }
let(:new_absorbing_organisation_user) { create(:user, organisation: new_absorbing_organisation) }
@ -1628,7 +1628,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1670,7 +1670,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
it "rolls back if there's an error" do
allow(Organisation).to receive(:find).with([merging_organisation_ids]).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(merging_organisation_ids).and_return(Organisation.find(merging_organisation_ids))
allow(Organisation).to receive(:find).with(new_absorbing_organisation.id).and_return(new_absorbing_organisation)
allow(new_absorbing_organisation).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
expect(Rails.logger).to receive(:error).with("Organisation merge failed with: Record invalid")
@ -1687,7 +1687,7 @@ RSpec.describe Merge::MergeOrganisationsService do
end
context "and merge date is provided" do
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids: [merging_organisation_ids], merge_date: Time.zone.yesterday) }
subject(:merge_organisations_service) { described_class.new(absorbing_organisation_id: new_absorbing_organisation.id, merging_organisation_ids:, merge_date: Time.zone.yesterday) }
it "sets merge date and absorbing organisation on merged organisations" do
merge_organisations_service.call

12
yarn.lock

@ -3117,7 +3117,7 @@ jest-worker@^27.4.5:
merge-stream "^2.0.0"
supports-color "^8.0.0"
jquery-ui@^1.12.1:
"jquery-ui@^1.12.1 <1.14.0":
version "1.13.3"
resolved "https://registry.yarnpkg.com/jquery-ui/-/jquery-ui-1.13.3.tgz#d9f5292b2857fa1f2fdbbe8f2e66081664eb9bc5"
integrity sha512-D2YJfswSJRh/B8M/zCowDpNFfwsDmtfnMPwjJTyvl+CBqzpYwQ+gFYIbUUlzijy/Qvoy30H1YhoSui4MNYpRwA==
@ -3741,10 +3741,10 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
rails_admin@3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/rails_admin/-/rails_admin-3.1.3.tgz#1da3f2214876f4ffd3a1db01452c28a8f7d4d989"
integrity sha512-79CBB2BMB3fSGPz1P8eNxCboHVlkBWBaxKxfo4QwCAFxsA3WAjfM0MeWUtGHI8Mn8XEZxCdEDz9oYlvlBpMtng==
rails_admin@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/rails_admin/-/rails_admin-3.3.0.tgz#58701b189e40b7c7f9a0a8ba2b996a41d5842017"
integrity sha512-sgdLMdJDOQmkEWYXY0uqLYxi7eMdhCEU4ZuKpVKdSssMoOr9iqCX8/sOP4ErRiC8Iez5x1vXVOv0Iki4ZKCNug==
dependencies:
"@babel/runtime" "^7.16.7"
"@fortawesome/fontawesome-free" ">=5.15.0 <7.0.0"
@ -3754,7 +3754,7 @@ rails_admin@3.1.3:
bootstrap "^5.1.3"
flatpickr "^4.6.9"
jquery "^3.6.0"
jquery-ui "^1.12.1"
jquery-ui "^1.12.1 <1.14.0"
randombytes@^2.1.0:
version "2.1.0"

Loading…
Cancel
Save