Browse Source

CLDC-2334 Add journey to fix soft validation errors only (#1615)

* Sends a correct email if there are only soft validations

* Add soft errors valid page

* Add soft errors confirm page

* Confirm the soft validations

* Reuse the how to fix template for check soft validations email

* Update email link

* Move soft validation confirmation to processor

* Correctly set the log status, remove redundant confirm_soft_validations

* Redirect successful upload to logs index and display a success banner

* Implement the soft validations only journey for sales logs

* Display the soft validation errors on the soft-errors-valid page

* Fix page alignment

* Fix tests by mapping housingneeds in csv hepler

* Add the sales soft validations to unpend_and_confirm_soft_validations

* Change naming

* Update method names

* refactor

* undo typo

* Only set the existing soft validations for correct types

* Fix path name

* Add missing error mappings for location fields

* Add missing tests and cancel button

* Change some wording

* Typos
pull/1626/head
kosiakkatrina 2 years ago committed by GitHub
parent
commit
79c4f9b74b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/controllers/bulk_upload_lettings_resume_controller.rb
  2. 43
      app/controllers/bulk_upload_lettings_soft_validations_check_controller.rb
  3. 1
      app/controllers/bulk_upload_sales_resume_controller.rb
  4. 43
      app/controllers/bulk_upload_sales_soft_validations_check_controller.rb
  5. 29
      app/mailers/bulk_upload_mailer.rb
  6. 35
      app/models/bulk_upload.rb
  7. 30
      app/models/forms/bulk_upload_lettings_soft_validations_check/confirm.rb
  8. 40
      app/models/forms/bulk_upload_lettings_soft_validations_check/confirm_soft_errors.rb
  9. 30
      app/models/forms/bulk_upload_sales_soft_validations_check/confirm.rb
  10. 40
      app/models/forms/bulk_upload_sales_soft_validations_check/confirm_soft_errors.rb
  11. 18
      app/services/bulk_upload/lettings/validator.rb
  12. 20
      app/services/bulk_upload/processor.rb
  13. 5
      app/services/bulk_upload/sales/validator.rb
  14. 1
      app/services/bulk_upload/sales/year2022/row_parser.rb
  15. 7
      app/views/bulk_upload_lettings_resume/fix_choice.html.erb
  16. 22
      app/views/bulk_upload_lettings_soft_validations_check/confirm.html.erb
  17. 32
      app/views/bulk_upload_lettings_soft_validations_check/confirm_soft_errors.html.erb
  18. 7
      app/views/bulk_upload_sales_resume/fix_choice.html.erb
  19. 22
      app/views/bulk_upload_sales_soft_validations_check/confirm.html.erb
  20. 32
      app/views/bulk_upload_sales_soft_validations_check/confirm_soft_errors.html.erb
  21. 17
      config/locales/en.yml
  22. 14
      config/routes.rb
  23. 23
      spec/mailers/bulk_upload_mailer_spec.rb
  24. 14
      spec/requests/bulk_upload_lettings_resume_controller_spec.rb
  25. 90
      spec/requests/bulk_upload_lettings_soft_validations_check_controller_spec.rb
  26. 96
      spec/requests/bulk_upload_sales_resume_controller_spec.rb
  27. 90
      spec/requests/bulk_upload_sales_soft_validations_check_controller_spec.rb
  28. 46
      spec/services/bulk_upload/lettings/log_creator_spec.rb
  29. 94
      spec/services/bulk_upload/processor_spec.rb
  30. 39
      spec/services/bulk_upload/sales/log_creator_spec.rb
  31. 14
      spec/support/bulk_upload/lettings_log_to_csv.rb

1
app/controllers/bulk_upload_lettings_resume_controller.rb

@ -9,6 +9,7 @@ class BulkUploadLettingsResumeController < ApplicationController
def show
@bulk_upload = current_user.bulk_uploads.find(params[:id])
@soft_errors_only = params[:soft_errors_only] == "true"
render form.view_path
end

43
app/controllers/bulk_upload_lettings_soft_validations_check_controller.rb

@ -0,0 +1,43 @@
class BulkUploadLettingsSoftValidationsCheckController < ApplicationController
include ActionView::Helpers::TextHelper
before_action :authenticate_user!
def show
@bulk_upload = current_user.bulk_uploads.find(params[:id])
render form.view_path
end
def update
@bulk_upload = current_user.bulk_uploads.find(params[:id])
if form.valid? && form.save!
if params[:page] == "confirm"
n_logs = pluralize(@bulk_upload.logs.count, "log")
flash[:notice] = "You’ve successfully uploaded #{n_logs}"
end
redirect_to form.next_path
else
render form.view_path
end
end
private
def form
@form ||= case params[:page]
when "confirm-soft-errors"
Forms::BulkUploadLettingsSoftValidationsCheck::ConfirmSoftErrors.new(form_params.merge(bulk_upload: @bulk_upload))
when "confirm"
Forms::BulkUploadLettingsSoftValidationsCheck::Confirm.new(form_params.merge(bulk_upload: @bulk_upload))
else
raise "invalid form"
end
end
def form_params
params.fetch(:form, {}).permit(:confirm_soft_errors)
end
end

1
app/controllers/bulk_upload_sales_resume_controller.rb

@ -9,6 +9,7 @@ class BulkUploadSalesResumeController < ApplicationController
def show
@bulk_upload = current_user.bulk_uploads.find(params[:id])
@soft_errors_only = params[:soft_errors_only] == "true"
render form.view_path
end

43
app/controllers/bulk_upload_sales_soft_validations_check_controller.rb

@ -0,0 +1,43 @@
class BulkUploadSalesSoftValidationsCheckController < ApplicationController
include ActionView::Helpers::TextHelper
before_action :authenticate_user!
def show
@bulk_upload = current_user.bulk_uploads.find(params[:id])
render form.view_path
end
def update
@bulk_upload = current_user.bulk_uploads.find(params[:id])
if form.valid? && form.save!
if params[:page] == "confirm"
n_logs = pluralize(@bulk_upload.logs.count, "log")
flash[:notice] = "You’ve successfully uploaded #{n_logs}"
end
redirect_to form.next_path
else
render form.view_path
end
end
private
def form
@form ||= case params[:page]
when "confirm-soft-errors"
Forms::BulkUploadSalesSoftValidationsCheck::ConfirmSoftErrors.new(form_params.merge(bulk_upload: @bulk_upload))
when "confirm"
Forms::BulkUploadSalesSoftValidationsCheck::Confirm.new(form_params.merge(bulk_upload: @bulk_upload))
else
raise "invalid form"
end
end
def form_params
params.fetch(:form, {}).permit(:confirm_soft_errors)
end
end

29
app/mailers/bulk_upload_mailer.rb

@ -5,16 +5,39 @@ class BulkUploadMailer < NotifyMailer
FAILED_CSV_ERRORS_TEMPLATE_ID = "e27abcd4-5295-48c2-b127-e9ee4b781b75".freeze
FAILED_FILE_SETUP_ERROR_TEMPLATE_ID = "24c9f4c7-96ad-470a-ba31-eb51b7cbafd9".freeze
FAILED_SERVICE_ERROR_TEMPLATE_ID = "c3f6288c-7a74-4e77-99ee-6c4a0f6e125a".freeze
HOW_FIX_UPLOAD_TEMPLATE_ID = "21a07b26-f625-4846-9f4d-39e30937aa24".freeze
HOW_TO_FIX_UPLOAD_TEMPLATE_ID = "21a07b26-f625-4846-9f4d-39e30937aa24".freeze
CHECK_SOFT_VALIDATIONS_TEMPLATE_ID = "21a07b26-f625-4846-9f4d-39e30937aa24".freeze
def send_how_fix_upload_mail(bulk_upload:)
def send_how_to_fix_upload_mail(bulk_upload:)
title = "We found #{pluralize(bulk_upload.bulk_upload_errors.count, 'error')} in your bulk upload"
description = "There was a problem with your #{bulk_upload.year_combo} #{bulk_upload.log_type} data. Check the error report below to fix these errors."
cta_link = bulk_upload.sales? ? start_bulk_upload_sales_resume_url(bulk_upload) : start_bulk_upload_lettings_resume_url(bulk_upload)
send_email(
bulk_upload.user.email,
HOW_FIX_UPLOAD_TEMPLATE_ID,
HOW_TO_FIX_UPLOAD_TEMPLATE_ID,
{
title:,
filename: bulk_upload.filename,
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
description:,
cta_link:,
},
)
end
def send_check_soft_validations_mail(bulk_upload:)
title = "Check your file data"
description = "Some of your #{bulk_upload.year_combo} #{bulk_upload.log_type} data might not be right. Click the link below to review the potential errors, and check your file to see if the data is correct."
cta_link = if bulk_upload.lettings?
bulk_upload_lettings_soft_validations_check_url(bulk_upload, page: "confirm-soft-errors")
else
bulk_upload_sales_soft_validations_check_url(bulk_upload, page: "confirm-soft-errors")
end
send_email(
bulk_upload.user.email,
CHECK_SOFT_VALIDATIONS_TEMPLATE_ID,
{
title:,
filename: bulk_upload.filename,

35
app/models/bulk_upload.rb

@ -72,6 +72,41 @@ class BulkUpload < ApplicationRecord
end
end
def unpend_and_confirm_soft_validations
logs.find_each do |log|
log.retirement_value_check = 0
if log.lettings?
log.pregnancy_value_check = 0
log.major_repairs_date_value_check = 0
log.void_date_value_check = 0
log.rent_value_check = 0
log.net_income_value_check = 0
log.carehome_charges_value_check = 0
elsif log.sales?
log.mortgage_value_check = 0
log.shared_ownership_deposit_value_check = 0
log.value_value_check = 0
log.savings_value_check = 0
log.income1_value_check = 0
log.deposit_value_check = 0
log.wheel_value_check = 0
log.extrabor_value_check = 0
log.grant_value_check = 0
log.staircase_bought_value_check = 0
log.deposit_and_mortgage_value_check = 0
log.old_persons_shared_ownership_value_check = 0
log.income2_value_check = 0
log.monthly_charges_value_check = 0
log.student_not_child_value_check = 0
log.discounted_sale_value_check = 0
log.buyer_livein_value_check = 0
log.percentage_discount_value_check = 0
end
log.save!
end
end
private
def generate_identifier

30
app/models/forms/bulk_upload_lettings_soft_validations_check/confirm.rb

@ -0,0 +1,30 @@
module Forms
module BulkUploadLettingsSoftValidationsCheck
class Confirm
include ActiveModel::Model
include ActiveModel::Attributes
include Rails.application.routes.url_helpers
attribute :bulk_upload
def view_path
"bulk_upload_lettings_soft_validations_check/confirm"
end
def back_path
page_bulk_upload_lettings_soft_validations_check_path(bulk_upload, page: "confirm-soft-errors")
end
def next_path
lettings_logs_path
end
def save!
processor = BulkUpload::Processor.new(bulk_upload:)
processor.approve_and_confirm_soft_validations
true
end
end
end
end

40
app/models/forms/bulk_upload_lettings_soft_validations_check/confirm_soft_errors.rb

@ -0,0 +1,40 @@
module Forms
module BulkUploadLettingsSoftValidationsCheck
class ConfirmSoftErrors
include ActiveModel::Model
include ActiveModel::Attributes
include Rails.application.routes.url_helpers
attribute :bulk_upload
attribute :confirm_soft_errors, :string
validates :confirm_soft_errors, presence: true
def options
[
OpenStruct.new(id: "yes", name: "Yes, these fields are correct"),
OpenStruct.new(id: "no", name: "No, there are errors"),
]
end
def view_path
"bulk_upload_lettings_soft_validations_check/confirm_soft_errors"
end
def next_path
case confirm_soft_errors
when "no"
page_bulk_upload_lettings_resume_path(bulk_upload, page: "fix-choice", soft_errors_only: true)
when "yes"
page_bulk_upload_lettings_soft_validations_check_path(bulk_upload, page: "confirm")
else
raise "invalid choice"
end
end
def save!
true
end
end
end
end

30
app/models/forms/bulk_upload_sales_soft_validations_check/confirm.rb

@ -0,0 +1,30 @@
module Forms
module BulkUploadSalesSoftValidationsCheck
class Confirm
include ActiveModel::Model
include ActiveModel::Attributes
include Rails.application.routes.url_helpers
attribute :bulk_upload
def view_path
"bulk_upload_sales_soft_validations_check/confirm"
end
def back_path
page_bulk_upload_sales_soft_validations_check_path(bulk_upload, page: "confirm-soft-errors")
end
def next_path
sales_logs_path
end
def save!
processor = BulkUpload::Processor.new(bulk_upload:)
processor.approve_and_confirm_soft_validations
true
end
end
end
end

40
app/models/forms/bulk_upload_sales_soft_validations_check/confirm_soft_errors.rb

@ -0,0 +1,40 @@
module Forms
module BulkUploadSalesSoftValidationsCheck
class ConfirmSoftErrors
include ActiveModel::Model
include ActiveModel::Attributes
include Rails.application.routes.url_helpers
attribute :bulk_upload
attribute :confirm_soft_errors, :string
validates :confirm_soft_errors, presence: true
def options
[
OpenStruct.new(id: "yes", name: "Yes, these fields are correct"),
OpenStruct.new(id: "no", name: "No, there are errors"),
]
end
def view_path
"bulk_upload_sales_soft_validations_check/confirm_soft_errors"
end
def next_path
case confirm_soft_errors
when "no"
page_bulk_upload_sales_resume_path(bulk_upload, page: "fix-choice", soft_errors_only: true)
when "yes"
page_bulk_upload_sales_soft_validations_check_path(bulk_upload, page: "confirm")
else
raise "invalid choice"
end
end
def save!
true
end
end
end
end

18
app/services/bulk_upload/lettings/validator.rb

@ -63,6 +63,24 @@ class BulkUpload::Lettings::Validator
.positive?
end
def soft_validation_errors_only?
errors = bulk_upload.bulk_upload_errors
errors.count == errors.where(category: "soft_validation").count && errors.count.positive?
end
def over_column_error_threshold?
fields = ("field_1".."field_134").to_a
percentage_threshold = (row_parsers.size * COLUMN_PERCENTAGE_ERROR_THRESHOLD).ceil
fields.any? do |field|
count = row_parsers.count { |row_parser| row_parser.errors[field].present? }
next if count < COLUMN_ABSOLUTE_ERROR_THRESHOLD
count > percentage_threshold
end
end
def any_logs_already_exist?
row_parsers.any?(&:log_already_exists?)
end

20
app/services/bulk_upload/processor.rb

@ -18,8 +18,10 @@ class BulkUpload::Processor
elsif validator.create_logs?
create_logs
if created_logs_but_incompleted?
send_how_fix_upload_mail
if validator.soft_validation_errors_only?
send_check_soft_validations_mail
elsif created_logs_but_incompleted?
send_how_to_fix_upload_mail
elsif created_logs_and_all_completed?
bulk_upload.unpend
send_success_mail
@ -38,11 +40,21 @@ class BulkUpload::Processor
bulk_upload.unpend
end
def approve_and_confirm_soft_validations
bulk_upload.unpend_and_confirm_soft_validations
end
private
def send_how_fix_upload_mail
def send_how_to_fix_upload_mail
BulkUploadMailer
.send_how_to_fix_upload_mail(bulk_upload:)
.deliver_later
end
def send_check_soft_validations_mail
BulkUploadMailer
.send_how_fix_upload_mail(bulk_upload:)
.send_check_soft_validations_mail(bulk_upload:)
.deliver_later
end

5
app/services/bulk_upload/sales/validator.rb

@ -59,6 +59,11 @@ class BulkUpload::Sales::Validator
row_parsers.any?(&:log_already_exists?)
end
def soft_validation_errors_only?
errors = bulk_upload.bulk_upload_errors
errors.count == errors.where(category: "soft_validation").count && errors.count.positive?
end
private
def any_logs_invalid?

1
app/services/bulk_upload/sales/year2022/row_parser.rb

@ -481,6 +481,7 @@ private
socprevten: %i[field_122],
mortgageused: %i[field_123 field_124 field_125],
soctenant: %i[field_39 field_113],
uprn: %i[],
}
end

7
app/views/bulk_upload_lettings_resume/fix_choice.html.erb

@ -30,7 +30,12 @@
:name,
legend: { hidden: true } %>
<%= f.govuk_submit %>
<div class="govuk-button-group">
<%= f.govuk_submit %>
<% if @soft_errors_only %>
<%= govuk_button_link_to "Cancel", bulk_upload_lettings_soft_validations_check_url(@bulk_upload, page: "confirm-soft-errors"), secondary: true %>
<% end %>
</div>
<% end %>
</div>
</div>

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

@ -0,0 +1,22 @@
<% content_for :before_content do %>
<%= govuk_back_link href: @form.back_path %>
<% end %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<span class="govuk-caption-l">Bulk upload for lettings (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">Are you sure you want to upload all logs from this bulk upload?</h1>
<p class="govuk-body">There are <%= pluralize(@bulk_upload.logs.count, "log") %> in this bulk upload, and <%= pluralize(@bulk_upload.bulk_upload_errors.count, "unexpected answer") %> will be marked as correct.</p>
<%= govuk_warning_text(icon_fallback_text: "Danger") do %>
You can not delete logs once you create them
<% end %>
<%= form_with model: @form, scope: :form, url: page_bulk_upload_lettings_soft_validations_check_path(@bulk_upload, page: "confirm"), method: :patch do |f| %>
<%= f.govuk_submit %>
<%= govuk_button_link_to "Cancel", @form.back_path, secondary: true %>
<% end %>
</div>
</div>

32
app/views/bulk_upload_lettings_soft_validations_check/confirm_soft_errors.html.erb

@ -0,0 +1,32 @@
<%= form_with model: @form, scope: :form, url: page_bulk_upload_lettings_soft_validations_check_path(@bulk_upload, page: "confirm-soft-errors"), method: :patch do |f| %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= f.govuk_error_summary %>
<span class="govuk-caption-l">Bulk upload for lettings (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">Check these <%= pluralize(@bulk_upload.bulk_upload_errors.count, "answer") %> </h1>
<p class="govuk-body-l">Some data from your bulk upload might not be right. Check your file for any errors in the fields below.</p>
<p class="govuk-body">
<%= @bulk_upload.filename %>
</p>
</div>
<div class="govuk-grid-column-full">
<% @bulk_upload.bulk_upload_errors.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %>
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: errors_for_row) %>
<% end %>
</div>
<div class="govuk-grid-column-full">
<%= f.govuk_collection_radio_buttons :confirm_soft_errors,
@form.options,
:id,
:name,
legend: { text: "Are these fields correct?", size: "l" } %>
<%= f.govuk_submit %>
</div>
</div>
<% end %>

7
app/views/bulk_upload_sales_resume/fix_choice.html.erb

@ -30,7 +30,12 @@
:name,
legend: { hidden: true } %>
<%= f.govuk_submit %>
<div class="govuk-button-group">
<%= f.govuk_submit %>
<% if @soft_errors_only %>
<%= govuk_button_link_to "Cancel", bulk_upload_sales_soft_validations_check_url(@bulk_upload, page: "confirm-soft-errors"), secondary: true %>
<% end %>
</div>
<% end %>
</div>
</div>

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

@ -0,0 +1,22 @@
<% content_for :before_content do %>
<%= govuk_back_link href: @form.back_path %>
<% end %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<span class="govuk-caption-l">Bulk upload for sales (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">Are you sure you want to upload all logs from this bulk upload?</h1>
<p class="govuk-body">There are <%= pluralize(@bulk_upload.logs.count, "log") %> in this bulk upload, and <%= pluralize(@bulk_upload.bulk_upload_errors.count, "unexpected answer") %> will be marked as correct.</p>
<%= govuk_warning_text(icon_fallback_text: "Danger") do %>
You can not delete logs once you create them
<% end %>
<%= form_with model: @form, scope: :form, url: page_bulk_upload_sales_soft_validations_check_path(@bulk_upload, page: "confirm"), method: :patch do |f| %>
<%= f.govuk_submit %>
<%= govuk_button_link_to "Cancel", @form.back_path, secondary: true %>
<% end %>
</div>
</div>

32
app/views/bulk_upload_sales_soft_validations_check/confirm_soft_errors.html.erb

@ -0,0 +1,32 @@
<%= form_with model: @form, scope: :form, url: page_bulk_upload_sales_soft_validations_check_path(@bulk_upload, page: "confirm-soft-errors"), method: :patch do |f| %>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= f.govuk_error_summary %>
<span class="govuk-caption-l">Bulk upload for sales (<%= @bulk_upload.year_combo %>)</span>
<h1 class="govuk-heading-l">Check these <%= pluralize(@bulk_upload.bulk_upload_errors.count, "answer") %> </h1>
<p class="govuk-body-l">Some data from your bulk upload might not be right. Check your file for any errors in the fields below.</p>
<p class="govuk-body">
<%= @bulk_upload.filename %>
</p>
</div>
<div class="govuk-grid-column-full">
<% @bulk_upload.bulk_upload_errors.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %>
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: errors_for_row) %>
<% end %>
</div>
<div class="govuk-grid-column-full">
<%= f.govuk_collection_radio_buttons :confirm_soft_errors,
@form.options,
:id,
:name,
legend: { text: "Are these fields correct?", size: "l" } %>
<%= f.govuk_submit %>
</div>
</div>
<% end %>

17
config/locales/en.yml

@ -71,8 +71,21 @@ en:
forms/bulk_upload_lettings_resume/fix_choice:
attributes:
choice:
blank: You must select how would you like to fix errors
inclusion: You must select one of the following options for how would like to fix errors
blank: Select how you would like to fix these errors
inclusion: You must select one of the following options for how you would like to fix these errors
forms/bulk_upload_lettings_soft_validations_check/confirm_soft_errors:
attributes:
confirm_soft_errors:
blank: You must select if there are errors in these fields
forms/bulk_upload_sales_soft_validations_check/confirm_soft_errors:
attributes:
confirm_soft_errors:
blank: You must select if there are errors in these fields
forms/bulk_upload_sales_resume/fix_choice:
attributes:
choice:
blank: Select how you would like to fix these errors
inclusion: You must select one of the following options for how you would like to fix these errors
activerecord:
errors:

14
config/routes.rb

@ -180,6 +180,13 @@ Rails.application.routes.draw do
end
end
resources :bulk_upload_lettings_soft_validations_check, path: "bulk-upload-soft-validations-check", only: %i[show update] do
member do
get "*page", to: "bulk_upload_lettings_soft_validations_check#show", as: "page"
patch "*page", to: "bulk_upload_lettings_soft_validations_check#update"
end
end
get "update-logs", to: "lettings_logs#update_logs"
end
@ -227,6 +234,13 @@ Rails.application.routes.draw do
patch "*page", to: "bulk_upload_sales_resume#update"
end
end
resources :bulk_upload_sales_soft_validations_check, path: "bulk-upload-soft-validations-check", only: %i[show update] do
member do
get "*page", to: "bulk_upload_sales_soft_validations_check#show", as: "page"
patch "*page", to: "bulk_upload_sales_soft_validations_check#update"
end
end
end
member do

23
spec/mailers/bulk_upload_mailer_spec.rb

@ -97,4 +97,27 @@ RSpec.describe BulkUploadMailer do
end
end
end
describe "#send_check_soft_validations_mail" do
before do
create(:bulk_upload_error, bulk_upload:, col: "A", field: "field_1", category: "soft_validation")
create(:bulk_upload_error, bulk_upload:, col: "E", field: "field_4", category: "soft_validation")
end
it "sends correctly formed email" do
expect(notify_client).to receive(:send_email).with(
email_address: bulk_upload.user.email,
template_id: described_class::CHECK_SOFT_VALIDATIONS_TEMPLATE_ID,
personalisation: {
title: "Check your file data",
filename: bulk_upload.filename,
upload_timestamp: bulk_upload.created_at.to_fs(:govuk_date_and_time),
description: "Some of your 2022/23 lettings data might not be right. Click the link below to review the potential errors, and check your file to see if the data is correct.",
cta_link: bulk_upload_lettings_soft_validations_check_url(bulk_upload, page: "confirm-soft-errors"),
},
)
mailer.send_check_soft_validations_mail(bulk_upload:)
end
end
end

14
spec/requests/bulk_upload_lettings_resume_controller_spec.rb

@ -27,6 +27,18 @@ RSpec.describe BulkUploadLettingsResumeController, type: :request do
expect(response.body).to include("2022/23")
expect(response.body).to include("How would you like to fix 2 errors?")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).not_to include("Cancel")
end
end
describe "GET /lettings-logs/bulk-upload-resume/:ID/fix-choice?soft_errors_only=true" do
it "displays a cancel button" do
get "/lettings-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice?soft_errors_only=true"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("Cancel")
end
end
@ -37,7 +49,7 @@ RSpec.describe BulkUploadLettingsResumeController, type: :request do
expect(response).to be_successful
expect(response.body).to include("You must select")
expect(response.body).to include("Select how you would like to fix these errors")
end
end

90
spec/requests/bulk_upload_lettings_soft_validations_check_controller_spec.rb

@ -0,0 +1,90 @@
require "rails_helper"
RSpec.describe BulkUploadLettingsSoftValidationsCheckController, type: :request do
let(:user) { create(:user) }
let(:bulk_upload) { create(:bulk_upload, :lettings, user:, bulk_upload_errors:) }
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2) }
before do
create_list(:lettings_log, 2, bulk_upload:)
sign_in user
end
describe "GET /lettings-logs/bulk-upload-soft-validations-check/:ID/confirm-soft-errors" do
it "shows the soft validation errors with confirmation question" do
get "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response.body).to include("Bulk upload for lettings")
expect(response.body).to include("2022/23")
expect(response.body).to include("Check these 2 answers")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Are these fields correct?")
end
it "shows the soft validation and lists the errors" do
get "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response.body).to include("Row #{bulk_upload_errors.first.row}")
expect(response.body).to include("Tenant code")
expect(response.body).to include("some error")
end
end
describe "PATCH /lettings-logs/bulk-upload-soft-validations-check/:ID/confirm-soft-errors" do
context "when no option selected" do
it "renders error message" do
patch "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response).to be_successful
expect(response.body).to include("You must select if there are errors in these fields")
end
end
context "when no is selected" do
it "sends them to the fix choice page" do
patch "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors", params: { form: { confirm_soft_errors: "no" } }
expect(response).to redirect_to("/lettings-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice?soft_errors_only=true")
end
end
context "when yes is selected" do
it "sends them to confirm choice" do
patch "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors", params: { form: { confirm_soft_errors: "yes" } }
expect(response).to redirect_to("/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm")
follow_redirect!
expect(response.body).not_to include("You’ve successfully uploaded")
end
end
end
describe "GET /lettings-logs/bulk-upload-soft-validations-check/:ID/confirm" do
it "renders page" do
get "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm"
expect(response).to be_successful
expect(response.body).to include("Are you sure you want to upload all logs from this bulk upload?")
expect(response.body).to include("There are 2 logs in this bulk upload, and 2 unexpected answers will be marked as correct.")
expect(response.body).not_to include("You’ve successfully uploaded")
end
end
describe "PATCH /lettings-logs/bulk-upload-soft-validations-check/:ID/confirm" do
let(:mock_processor) { instance_double(BulkUpload::Processor, approve_and_confirm_soft_validations: nil) }
it "approves logs for creation" do
allow(BulkUpload::Processor).to receive(:new).with(bulk_upload:).and_return(mock_processor)
patch "/lettings-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm"
expect(mock_processor).to have_received(:approve_and_confirm_soft_validations)
expect(response).to redirect_to("/lettings-logs")
follow_redirect!
expect(response.body).to include("You’ve successfully uploaded 2 logs")
end
end
end

96
spec/requests/bulk_upload_sales_resume_controller_spec.rb

@ -0,0 +1,96 @@
require "rails_helper"
RSpec.describe BulkUploadSalesResumeController, type: :request do
let(:user) { create(:user) }
let(:bulk_upload) { create(:bulk_upload, :sales, user:, bulk_upload_errors:) }
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2) }
before do
sign_in user
end
describe "GET /sales-logs/bulk-upload-resume/:ID/start" do
it "redirects to choice page" do
get "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/start"
expect(response).to redirect_to("/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice")
end
end
describe "GET /sales-logs/bulk-upload-resume/:ID/fix-choice" do
it "renders the page correctly" do
get "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2022/23")
expect(response.body).to include("How would you like to fix 2 errors?")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).not_to include("Cancel")
end
end
describe "GET /sales-logs/bulk-upload-resume/:ID/fix-choice?soft_errors_only=true" do
it "displays a cancel button" do
get "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice?soft_errors_only=true"
expect(response).to be_successful
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("Cancel")
end
end
describe "PATCH /sales-logs/bulk-upload-resume/:ID/fix-choice" do
context "when no option selected" do
it "renders error message" do
patch "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice"
expect(response).to be_successful
expect(response.body).to include("Select how you would like to fix these errors")
end
end
context "when upload again selected" do
it "sends them to relevant report" do
patch "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice", params: { form: { choice: "upload-again" } }
expect(response).to redirect_to("/sales-logs/bulk-upload-results/#{bulk_upload.id}")
end
end
context "when fix inline selected" do
it "sends them to confirm choice" do
patch "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice", params: { form: { choice: "create-fix-inline" } }
expect(response).to redirect_to("/sales-logs/bulk-upload-resume/#{bulk_upload.id}/confirm")
end
end
end
describe "GET /sales-logs/bulk-upload-resume/:ID/confirm" do
it "renders page" do
get "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/confirm"
expect(response).to be_successful
expect(response.body).to include("Are you sure")
end
end
describe "PATCH /sales-logs/bulk-upload-resume/:ID/confirm" do
let(:mock_processor) { instance_double(BulkUpload::Processor, approve: nil) }
it "approves logs for creation" do
allow(BulkUpload::Processor).to receive(:new).with(bulk_upload:).and_return(mock_processor)
patch "/sales-logs/bulk-upload-resume/#{bulk_upload.id}/confirm"
expect(mock_processor).to have_received(:approve)
expect(response).to redirect_to("/sales-logs/bulk-upload-results/#{bulk_upload.id}/resume")
end
end
end

90
spec/requests/bulk_upload_sales_soft_validations_check_controller_spec.rb

@ -0,0 +1,90 @@
require "rails_helper"
RSpec.describe BulkUploadSalesSoftValidationsCheckController, type: :request do
let(:user) { create(:user) }
let(:bulk_upload) { create(:bulk_upload, :sales, user:, bulk_upload_errors:) }
let(:bulk_upload_errors) { create_list(:bulk_upload_error, 2) }
before do
create_list(:sales_log, 2, bulk_upload:)
sign_in user
end
describe "GET /sales-logs/bulk-upload-soft-validations-check/:ID/confirm-soft-errors" do
it "shows the soft validation errors with confirmation question" do
get "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response.body).to include("Bulk upload for sales")
expect(response.body).to include("2022/23")
expect(response.body).to include("Check these 2 answers")
expect(response.body).to include(bulk_upload.filename)
expect(response.body).to include("Are these fields correct?")
end
it "shows the soft validation and lists the errors" do
get "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response.body).to include("Row #{bulk_upload_errors.first.row}")
expect(response.body).to include("Purchaser code")
expect(response.body).to include("some error")
end
end
describe "PATCH /sales-logs/bulk-upload-soft-validations-check/:ID/confirm-soft-errors" do
context "when no option selected" do
it "renders error message" do
patch "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors"
expect(response).to be_successful
expect(response.body).to include("You must select if there are errors in these fields")
end
end
context "when no is selected" do
it "sends them to the fix choice page" do
patch "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors", params: { form: { confirm_soft_errors: "no" } }
expect(response).to redirect_to("/sales-logs/bulk-upload-resume/#{bulk_upload.id}/fix-choice?soft_errors_only=true")
end
end
context "when yes is selected" do
it "sends them to confirm choice" do
patch "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm-soft-errors", params: { form: { confirm_soft_errors: "yes" } }
expect(response).to redirect_to("/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm")
follow_redirect!
expect(response.body).not_to include("You’ve successfully uploaded")
end
end
end
describe "GET /sales-logs/bulk-upload-soft-validations-check/:ID/confirm" do
it "renders page" do
get "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm"
expect(response).to be_successful
expect(response.body).to include("Are you sure you want to upload all logs from this bulk upload?")
expect(response.body).to include("There are 2 logs in this bulk upload, and 2 unexpected answers will be marked as correct.")
expect(response.body).not_to include("You’ve successfully uploaded")
end
end
describe "PATCH /sales-logs/bulk-upload-soft-validations-check/:ID/confirm" do
let(:mock_processor) { instance_double(BulkUpload::Processor, approve_and_confirm_soft_validations: nil) }
it "approves logs for creation" do
allow(BulkUpload::Processor).to receive(:new).with(bulk_upload:).and_return(mock_processor)
patch "/sales-logs/bulk-upload-soft-validations-check/#{bulk_upload.id}/confirm"
expect(mock_processor).to have_received(:approve_and_confirm_soft_validations)
expect(response).to redirect_to("/sales-logs")
follow_redirect!
expect(response.body).to include("You’ve successfully uploaded 2 logs")
end
end
end

46
spec/services/bulk_upload/lettings/log_creator_spec.rb

@ -129,6 +129,52 @@ RSpec.describe BulkUpload::Lettings::LogCreator do
end
end
context "with a valid csv and soft validations" do
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) do
build(
:lettings_log,
:completed,
renttype: 3,
age1: 22,
age1_known: 0,
ecstat1: 5,
owning_organisation: owning_org,
managing_organisation: owning_org,
created_by: user,
national: 18,
waityear: 9,
joint: 2,
tenancy: 9,
ppcodenk: 0,
)
end
before do
file.write(BulkUpload::LettingsLogToCsv.new(log:, col_offset: 0).to_2022_csv_row)
file.rewind
end
it "creates a new log" do
expect { service.call }.to change(LettingsLog, :count)
end
it "creates a log with pending status" do
service.call
expect(LettingsLog.last.status).to eql("pending")
end
it "does not set unanswered soft validations" do
service.call
log = LettingsLog.last
expect(log.age1).to be(22)
expect(log.ecstat1).to be(5)
expect(log.retirement_value_check).to be(nil)
end
end
context "when valid csv with existing log" do
xit "what should happen?"
end

94
spec/services/bulk_upload/processor_spec.rb

@ -224,16 +224,104 @@ RSpec.describe BulkUpload::Processor do
expect { processor.call }.to change(LettingsLog.pending, :count).by(1)
end
it "sends how_fix_upload_mail" do
it "sends how_to_fix_upload_mail" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
allow(BulkUploadMailer).to receive(:send_how_fix_upload_mail).and_return(mail_double)
allow(BulkUploadMailer).to receive(:send_how_to_fix_upload_mail).and_return(mail_double)
processor.call
expect(BulkUploadMailer).to have_received(:send_how_fix_upload_mail)
expect(BulkUploadMailer).to have_received(:send_how_to_fix_upload_mail)
expect(mail_double).to have_received(:deliver_later)
end
it "calls log creator" do
log_creator_double = instance_double(BulkUpload::Lettings::LogCreator, call: nil)
allow(BulkUpload::Lettings::LogCreator).to receive(:new).and_return(log_creator_double)
processor.call
expect(BulkUpload::Lettings::LogCreator).to have_received(:new).with(bulk_upload:, path:)
end
end
context "when a bulk upload has logs with only soft validations triggered" do
let(:mock_downloader) do
instance_double(
BulkUpload::Downloader,
call: nil,
path:,
delete_local_file!: nil,
)
end
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) do
build(
:lettings_log,
:completed,
renttype: 3,
age1: 20,
ecstat1: 5,
owning_organisation: owning_org,
managing_organisation: owning_org,
created_by: nil,
national: 18,
waityear: 9,
joint: 2,
tenancy: 2,
ppcodenk: 0,
voiddate: Date.new(2022, 1, 1),
reason: 40,
leftreg: 3,
mrcdate: nil,
startdate: Date.new(2022, 10, 1),
tenancylength: nil,
)
end
before do
FormHandler.instance.use_real_forms!
file.write(BulkUpload::LettingsLogToCsv.new(log:, col_offset: 0).to_2022_csv_row)
file.rewind
allow(BulkUpload::Downloader).to receive(:new).with(bulk_upload:).and_return(mock_downloader)
allow(FeatureToggle).to receive(:bulk_upload_duplicate_log_check_enabled?).and_return(true)
end
after do
FormHandler.instance.use_fake_forms!
end
it "creates pending log" do
expect { processor.call }.to change(LettingsLog.pending, :count).by(1)
end
it "sends check_soft_validations_mail" do
mail_double = instance_double("ActionMailer::MessageDelivery", deliver_later: nil)
allow(BulkUploadMailer).to receive(:send_check_soft_validations_mail).and_return(mail_double)
allow(BulkUploadMailer).to receive(:send_how_to_fix_upload_mail).and_return(mail_double)
processor.call
expect(BulkUploadMailer).to have_received(:send_check_soft_validations_mail)
expect(BulkUploadMailer).not_to have_received(:send_how_to_fix_upload_mail)
expect(mail_double).to have_received(:deliver_later)
end
it "calls log creator" do
log_creator_double = instance_double(BulkUpload::Lettings::LogCreator, call: nil)
allow(BulkUpload::Lettings::LogCreator).to receive(:new).and_return(log_creator_double)
processor.call
expect(BulkUpload::Lettings::LogCreator).to have_received(:new).with(bulk_upload:, path:)
end
end
context "when upload has no setup errors something blocks log creation" do

39
spec/services/bulk_upload/sales/log_creator_spec.rb

@ -130,5 +130,44 @@ RSpec.describe BulkUpload::Sales::LogCreator do
context "when valid csv with existing log" do
xit "what should happen?"
end
context "with a valid csv and soft validations" do
let(:file) { Tempfile.new }
let(:path) { file.path }
let(:log) do
build(
:sales_log,
:completed,
age1: 30,
age1_known: 0,
ecstat1: 5,
owning_organisation: owning_org,
created_by: user,
)
end
before do
file.write(BulkUpload::SalesLogToCsv.new(log:, col_offset: 0).to_2022_csv_row)
file.rewind
end
it "creates a new log" do
expect { service.call }.to change(SalesLog, :count)
end
it "creates a log with pending status" do
service.call
expect(SalesLog.last.status).to eql("pending")
end
it "does not set unanswered soft validations" do
service.call
log = SalesLog.last
expect(log.age1).to be(30)
expect(log.ecstat1).to be(5)
expect(log.retirement_value_check).to be(nil)
end
end
end
end

14
spec/support/bulk_upload/lettings_log_to_csv.rb

@ -123,15 +123,15 @@ class BulkUpload::LettingsLogToCsv
log.benefits,
log.earnings, # 50
net_income_known,
nil,
log.reason,
log.reasonother,
nil,
nil,
nil,
nil,
nil,
nil,
nil, # 60
log.housingneeds_a,
log.housingneeds_b,
log.housingneeds_c,
log.housingneeds_f,
log.housingneeds_g,
log.housingneeds_h, # 60
log.prevten,
log.prevloc,
((log.ppostcode_full || "").split(" ") || [""]).first,

Loading…
Cancel
Save