Browse Source
* Empty commit * feat: base lettings behaviour * feat: formatting improvements * Empty commit * Empty commit * Empty commit * refactor: lint * feat: more page styling * feat: update tests * refactor: lint * feat: add requests spec * refactor: simplify * feat: add tests * feat: copy change to reflect that the count in the header is not necessarily as large as the errors shown (it excludes duplicate errors on fields, and not_answered errors) * feat: copy changes to sales as well * feat: remove LegacyBulkUpload MVC * feat: fix typo * feat: update tests * feat: mark additional not_answered sales q * feat: update routing and only display warnign text when errors will be cleared * feat: update copy and error rows * refactor: lint * feat: don't show soft validations in deletion report * feat: update routing so deletion report is not shown once logs uploaded * feat: update tests * feat: make unique count track repeated errors across rows * refactor: lintpull/2163/head
natdeanlewissoftwire
11 months ago
committed by
GitHub
30 changed files with 472 additions and 407 deletions
@ -1,26 +0,0 @@ |
|||||||
class BulkUploadController < ApplicationController |
|
||||||
before_action :authenticate_user! |
|
||||||
|
|
||||||
def show |
|
||||||
@bulk_upload = LegacyBulkUpload.new(nil, nil) |
|
||||||
render "logs/bulk_upload" |
|
||||||
end |
|
||||||
|
|
||||||
def bulk_upload |
|
||||||
file = upload_params.tempfile |
|
||||||
content_type = upload_params.content_type |
|
||||||
@bulk_upload = LegacyBulkUpload.new(file, content_type) |
|
||||||
@bulk_upload.process(current_user) |
|
||||||
if @bulk_upload.errors.present? |
|
||||||
render "logs/bulk_upload", status: :unprocessable_entity |
|
||||||
else |
|
||||||
redirect_to(lettings_logs_path) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
private |
|
||||||
|
|
||||||
def upload_params |
|
||||||
params.require("bulk_upload")["lettings_log_bulk_upload"] |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,28 @@ |
|||||||
|
module Forms |
||||||
|
module BulkUploadLettingsResume |
||||||
|
class DeletionReport |
||||||
|
include ActiveModel::Model |
||||||
|
include ActiveModel::Attributes |
||||||
|
include Rails.application.routes.url_helpers |
||||||
|
|
||||||
|
attribute :bulk_upload |
||||||
|
|
||||||
|
def view_path |
||||||
|
"bulk_upload_lettings_resume/deletion_report" |
||||||
|
end |
||||||
|
|
||||||
|
def preflight_valid? |
||||||
|
bulk_upload.choice != "create-fix-inline" && bulk_upload.choice != "bulk-confirm-soft-validations" |
||||||
|
end |
||||||
|
|
||||||
|
def preflight_redirect |
||||||
|
case bulk_upload.choice |
||||||
|
when "create-fix-inline" |
||||||
|
page_bulk_upload_lettings_resume_path(bulk_upload, :chosen) |
||||||
|
when "bulk-confirm-soft-validations" |
||||||
|
page_bulk_upload_lettings_soft_validations_check_path(bulk_upload, :chosen) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,197 +0,0 @@ |
|||||||
class LegacyBulkUpload |
|
||||||
include ActiveModel::Model |
|
||||||
include ActiveModel::Validations |
|
||||||
include ActiveModel::Conversion |
|
||||||
|
|
||||||
SPREADSHEET_CONTENT_TYPES = %w[ |
|
||||||
application/vnd.ms-excel |
|
||||||
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet |
|
||||||
].freeze |
|
||||||
|
|
||||||
FIRST_DATA_ROW = 7 |
|
||||||
|
|
||||||
def initialize(file, content_type) |
|
||||||
@file = file |
|
||||||
@content_type = content_type |
|
||||||
end |
|
||||||
|
|
||||||
def process(current_user) |
|
||||||
return unless valid_content_type? |
|
||||||
|
|
||||||
xlsx = Roo::Spreadsheet.open(@file, extension: :xlsx) |
|
||||||
sheet = xlsx.sheet(0) |
|
||||||
last_row = sheet.last_row |
|
||||||
if last_row < FIRST_DATA_ROW |
|
||||||
errors.add(:lettings_log_bulk_upload, "No data found") |
|
||||||
else |
|
||||||
data_range = FIRST_DATA_ROW..last_row |
|
||||||
data_range.map do |row_num| |
|
||||||
row = sheet.row(row_num) |
|
||||||
# owning_organisation = Organisation.find(row[111]) |
|
||||||
# managing_organisation = Organisation.find(row[113]) |
|
||||||
lettings_log = LettingsLog.create!( |
|
||||||
owning_organisation: current_user.organisation, |
|
||||||
managing_organisation: current_user.organisation, |
|
||||||
created_by: current_user, |
|
||||||
) |
|
||||||
map_row(row).each do |attr_key, attr_val| |
|
||||||
_update = lettings_log.update(attr_key => attr_val) |
|
||||||
rescue ArgumentError |
|
||||||
# TODO: determine what we want to do when bulk upload contains totally invalid data for a field. |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def valid_content_type? |
|
||||||
if SPREADSHEET_CONTENT_TYPES.include?(@content_type) |
|
||||||
true |
|
||||||
else |
|
||||||
errors.add(:lettings_log_bulk_upload, "Invalid file type") |
|
||||||
false |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
def map_row(row) |
|
||||||
{ |
|
||||||
lettype: row[1], |
|
||||||
# reg_num_la_core_code: row[3], |
|
||||||
# managementgroup: row[4], |
|
||||||
# schemecode: row[5], |
|
||||||
# firstletting: row[6], |
|
||||||
tenancycode: row[7], |
|
||||||
startertenancy: row[8], |
|
||||||
tenancy: row[9], |
|
||||||
tenancyother: row[10], |
|
||||||
# tenancyduration: row[11], |
|
||||||
hhmemb: hhmemb(row), |
|
||||||
age1: row[12], |
|
||||||
age2: row[13], |
|
||||||
age3: row[14], |
|
||||||
age4: row[15], |
|
||||||
age5: row[16], |
|
||||||
age6: row[17], |
|
||||||
age7: row[18], |
|
||||||
age8: row[19], |
|
||||||
sex1: row[20], |
|
||||||
sex2: row[21], |
|
||||||
sex3: row[22], |
|
||||||
sex4: row[23], |
|
||||||
sex5: row[24], |
|
||||||
sex6: row[25], |
|
||||||
sex7: row[26], |
|
||||||
sex8: row[27], |
|
||||||
relat2: row[28], |
|
||||||
relat3: row[29], |
|
||||||
relat4: row[30], |
|
||||||
relat5: row[31], |
|
||||||
relat6: row[32], |
|
||||||
relat7: row[33], |
|
||||||
relat8: row[34], |
|
||||||
ecstat1: row[35], |
|
||||||
ecstat2: row[36], |
|
||||||
ecstat3: row[37], |
|
||||||
ecstat4: row[38], |
|
||||||
ecstat5: row[39], |
|
||||||
ecstat6: row[40], |
|
||||||
ecstat7: row[41], |
|
||||||
ecstat8: row[42], |
|
||||||
ethnic: row[43], |
|
||||||
national: row[44], |
|
||||||
armedforces: row[45], |
|
||||||
reservist: row[46], |
|
||||||
preg_occ: row[47], |
|
||||||
hb: row[48], |
|
||||||
benefits: row[49], |
|
||||||
net_income_known: row[50].present? ? 1 : nil, |
|
||||||
earnings: row[50], |
|
||||||
# increfused: row[51], |
|
||||||
reason: row[52], |
|
||||||
reasonother: row[53], |
|
||||||
underoccupation_benefitcap: row[54], |
|
||||||
housingneeds_a: row[55], |
|
||||||
housingneeds_b: row[56], |
|
||||||
housingneeds_c: row[57], |
|
||||||
housingneeds_f: row[58], |
|
||||||
housingneeds_g: row[59], |
|
||||||
housingneeds_h: row[60], |
|
||||||
prevten: row[61], |
|
||||||
prevloc: row[62], |
|
||||||
# prevpco_unknown: row[65], |
|
||||||
layear: row[66], |
|
||||||
waityear: row[67], |
|
||||||
homeless: row[68], |
|
||||||
reasonpref: row[69], |
|
||||||
rp_homeless: row[70], |
|
||||||
rp_insan_unsat: row[71], |
|
||||||
rp_medwel: row[72], |
|
||||||
rp_hardship: row[73], |
|
||||||
rp_dontknow: row[74], |
|
||||||
cbl: row[75], |
|
||||||
chr: row[76], |
|
||||||
cap: row[77], |
|
||||||
# referral_source: row[78], |
|
||||||
period: row[79], |
|
||||||
brent: row[80], |
|
||||||
scharge: row[81], |
|
||||||
pscharge: row[82], |
|
||||||
supcharg: row[83], |
|
||||||
tcharge: row[84], |
|
||||||
# tcharge_care_homes: row[85], |
|
||||||
# no_rent_or_charge: row[86], |
|
||||||
hbrentshortfall: row[87], |
|
||||||
tshortfall: row[88], |
|
||||||
voiddate: row[89].to_s + row[90].to_s + row[91].to_s, |
|
||||||
majorrepairs: row[92].present? ? "1" : nil, |
|
||||||
mrcdate: row[92].to_s + row[93].to_s + row[94].to_s, |
|
||||||
# supported_scheme: row[95], |
|
||||||
startdate: date_time(row[98], row[97], row[96]), |
|
||||||
# startdate_day: row[96], |
|
||||||
# startdate_month: row[97], |
|
||||||
# startdate_year: row[98], |
|
||||||
offered: row[99], |
|
||||||
# property_reference: row[100], |
|
||||||
beds: row[101], |
|
||||||
unittype_gn: row[102], |
|
||||||
builtype: row[103], |
|
||||||
wchair: row[104], |
|
||||||
property_relet: row[105], |
|
||||||
rsnvac: row[106], |
|
||||||
la: row[107], |
|
||||||
# row[110] removed |
|
||||||
# row[111] is owning organisation used above |
|
||||||
# username: row[112], |
|
||||||
# row[113] is managing organisation used above |
|
||||||
leftreg: row[114], |
|
||||||
# uprn: row[115], |
|
||||||
incfreq: row[116], |
|
||||||
# sheltered_accom: row[117], |
|
||||||
illness: row[118], |
|
||||||
illness_type_1: row[119], |
|
||||||
illness_type_2: row[120], |
|
||||||
illness_type_3: row[121], |
|
||||||
illness_type_4: row[122], |
|
||||||
illness_type_8: row[123], |
|
||||||
illness_type_5: row[124], |
|
||||||
illness_type_6: row[125], |
|
||||||
illness_type_7: row[126], |
|
||||||
illness_type_9: row[127], |
|
||||||
illness_type_10: row[128], |
|
||||||
# london_affordable: row[129], |
|
||||||
rent_type: row[130], |
|
||||||
irproduct_other: row[131], |
|
||||||
# data_protection: row[132], |
|
||||||
declaration: 1, |
|
||||||
} |
|
||||||
end |
|
||||||
|
|
||||||
def date_time(year, month, day) |
|
||||||
return unless year && month && day |
|
||||||
|
|
||||||
Time.zone.local("20#{year}", month.to_s, day.to_s) |
|
||||||
end |
|
||||||
|
|
||||||
def hhmemb(row) |
|
||||||
[14, 15, 16, 17, 18, 19, 20].count { |idx| row[idx].present? } |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,31 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link(href: :back) %> |
||||||
|
<% 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"><%= answers_to_be_deleted_title_text(@bulk_upload) %></h1> |
||||||
|
|
||||||
|
<p>The following cells contain data this is incorrect.</p> |
||||||
|
<p>If you upload the logs, these answers will be deleted. You will have to re-enter the data on the site and resolve these errors.</p> |
||||||
|
<p>If you do not want these answers to be deleted, correct the data in the CSV and upload the file again.</p> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">File: <%= @bulk_upload.filename %></h2> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="govuk-grid-row"> |
||||||
|
<div class="govuk-grid-column-full"> |
||||||
|
<% @bulk_upload.bulk_upload_errors.order_by_row.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %> |
||||||
|
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: all_answers_to_be_cleared(errors_for_row)) %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<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 %> |
||||||
|
<% end %> |
||||||
|
</div> |
@ -0,0 +1,31 @@ |
|||||||
|
<% content_for :before_content do %> |
||||||
|
<%= govuk_back_link(href: :back) %> |
||||||
|
<% 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"><%= answers_to_be_deleted_title_text(@bulk_upload) %></h1> |
||||||
|
|
||||||
|
<p>The following cells contain data this is incorrect.</p> |
||||||
|
<p>If you upload the logs, these answers will be deleted. You will have to re-enter the data on the site and resolve these errors.</p> |
||||||
|
<p>If you do not want these answers to be deleted, correct the data in the CSV and upload the file again.</p> |
||||||
|
|
||||||
|
<h2 class="govuk-heading-m">File: <%= @bulk_upload.filename %></h2> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="govuk-grid-row"> |
||||||
|
<div class="govuk-grid-column-full"> |
||||||
|
<% @bulk_upload.bulk_upload_errors.order_by_row.order_by_cell.group_by(&:row).each do |_row, errors_for_row| %> |
||||||
|
<%= render BulkUploadErrorRowComponent.new(bulk_upload_errors: all_answers_to_be_cleared(errors_for_row)) %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<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 %> |
||||||
|
<% end %> |
||||||
|
</div> |
@ -1,11 +0,0 @@ |
|||||||
<% content_for :title, "Bulk upload" %> |
|
||||||
|
|
||||||
<%= form_for @bulk_upload, scope: :bulk_upload, url: bulk_upload_lettings_logs_path, method: "post" do |f| %> |
|
||||||
<%= f.govuk_error_summary %> |
|
||||||
|
|
||||||
<%= f.govuk_file_field :lettings_log_bulk_upload, |
|
||||||
label: { text: content_for(:title), size: "l" }, |
|
||||||
hint: { text: "Upload a spreadsheet using the template" } %> |
|
||||||
|
|
||||||
<%= f.govuk_submit "Upload" %> |
|
||||||
<% end %> |
|
@ -0,0 +1,139 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe LogsHelper, type: :helper do |
||||||
|
describe "#unique_answers_to_be_cleared" do |
||||||
|
let(:result) { unique_answers_to_be_cleared(bulk_upload) } |
||||||
|
|
||||||
|
context "with a lettings bulk upload with various errors" do |
||||||
|
let(:bulk_upload) { create(:bulk_upload, :lettings) } |
||||||
|
|
||||||
|
context "with one row" do |
||||||
|
before do |
||||||
|
errors = [OpenStruct.new(attribute: "field_50", message: "you must answer field 50", category: :not_answered), |
||||||
|
OpenStruct.new(attribute: "field_60", message: "some compound error", category: :other_category), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some compound error", category: :other_category), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some other compound error that overlaps with a previous error field", category: :another_category), |
||||||
|
OpenStruct.new(attribute: "field_62", message: "some other compound error that overlaps with a previous error field", category: :another_category), |
||||||
|
OpenStruct.new(attribute: "field_63", message: "some soft validation error", category: :soft_validation)] |
||||||
|
errors.each do |error| |
||||||
|
bulk_upload.bulk_upload_errors.create!( |
||||||
|
field: error.attribute, |
||||||
|
error: error.message, |
||||||
|
tenant_code: "test", |
||||||
|
property_ref: "test", |
||||||
|
row: "test", |
||||||
|
cell: "test", |
||||||
|
col: "test", |
||||||
|
category: error.category, |
||||||
|
) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
it "returns the correct unique answers to be cleared" do |
||||||
|
expect(result.count).to eq(3) |
||||||
|
expect(result.map(&:field)).to match_array(%w[field_60 field_61 field_62]) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "with multiple rows" do |
||||||
|
before do |
||||||
|
errors = [OpenStruct.new(attribute: "field_50", message: "you must answer field 50", category: :not_answered, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_60", message: "some compound error", category: :other_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some compound error", category: :other_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_62", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_63", message: "some soft validation error", category: :soft_validation, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_50", message: "you must answer field 50", category: :not_answered, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_60", message: "some compound error", category: :other_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some compound error", category: :other_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_62", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_63", message: "some soft validation error", category: :soft_validation, row: 2)] |
||||||
|
errors.each do |error| |
||||||
|
bulk_upload.bulk_upload_errors.create!( |
||||||
|
field: error.attribute, |
||||||
|
error: error.message, |
||||||
|
tenant_code: "test", |
||||||
|
property_ref: "test", |
||||||
|
row: error.row, |
||||||
|
cell: "test", |
||||||
|
col: "test", |
||||||
|
category: error.category, |
||||||
|
) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
it "returns the correct unique answers to be cleared" do |
||||||
|
expect(result.count).to eq(6) |
||||||
|
expect(result.map(&:field)).to match_array(%w[field_60 field_61 field_62 field_60 field_61 field_62]) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "with a sales bulk upload with various errors" do |
||||||
|
let(:bulk_upload) { create(:bulk_upload, :sales) } |
||||||
|
|
||||||
|
context "with one row" do |
||||||
|
before do |
||||||
|
errors = [OpenStruct.new(attribute: "field_50", message: "you must answer field 50", category: :not_answered), |
||||||
|
OpenStruct.new(attribute: "field_60", message: "some compound error", category: :other_category), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some compound error", category: :other_category), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some other compound error that overlaps with a previous error field", category: :another_category), |
||||||
|
OpenStruct.new(attribute: "field_62", message: "some other compound error that overlaps with a previous error field", category: :another_category), |
||||||
|
OpenStruct.new(attribute: "field_63", message: "some soft validation error", category: :soft_validation)] |
||||||
|
errors.each do |error| |
||||||
|
bulk_upload.bulk_upload_errors.create!( |
||||||
|
field: error.attribute, |
||||||
|
error: error.message, |
||||||
|
tenant_code: "test", |
||||||
|
property_ref: "test", |
||||||
|
row: "test", |
||||||
|
cell: "test", |
||||||
|
col: "test", |
||||||
|
category: error.category, |
||||||
|
) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
it "returns the correct unique answers to be cleared" do |
||||||
|
expect(result.count).to eq(3) |
||||||
|
expect(result.map(&:field)).to match_array(%w[field_60 field_61 field_62]) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "with multiple rows" do |
||||||
|
before do |
||||||
|
errors = [OpenStruct.new(attribute: "field_50", message: "you must answer field 50", category: :not_answered, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_60", message: "some compound error", category: :other_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some compound error", category: :other_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_62", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_63", message: "some soft validation error", category: :soft_validation, row: 1), |
||||||
|
OpenStruct.new(attribute: "field_50", message: "you must answer field 50", category: :not_answered, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_60", message: "some compound error", category: :other_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some compound error", category: :other_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_61", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_62", message: "some other compound error that overlaps with a previous error field", category: :another_category, row: 2), |
||||||
|
OpenStruct.new(attribute: "field_63", message: "some soft validation error", category: :soft_validation, row: 2)] |
||||||
|
errors.each do |error| |
||||||
|
bulk_upload.bulk_upload_errors.create!( |
||||||
|
field: error.attribute, |
||||||
|
error: error.message, |
||||||
|
tenant_code: "test", |
||||||
|
property_ref: "test", |
||||||
|
row: error.row, |
||||||
|
cell: "test", |
||||||
|
col: "test", |
||||||
|
category: error.category, |
||||||
|
) |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
it "returns the correct unique answers to be cleared" do |
||||||
|
expect(result.count).to eq(6) |
||||||
|
expect(result.map(&:field)).to match_array(%w[field_60 field_61 field_62 field_60 field_61 field_62]) |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,126 +0,0 @@ |
|||||||
require "rails_helper" |
|
||||||
|
|
||||||
RSpec.describe BulkUploadController, type: :request do |
|
||||||
let(:url) { "/lettings-logs/bulk-upload" } |
|
||||||
let(:user) { FactoryBot.create(:user) } |
|
||||||
let(:organisation) { user.organisation } |
|
||||||
let(:valid_file) { fixture_file_upload("2021_22_lettings_bulk_upload.xlsx", "application/vnd.ms-excel") } |
|
||||||
let(:invalid_file) { fixture_file_upload("random.txt", "text/plain") } |
|
||||||
let(:empty_file) { fixture_file_upload("2021_22_lettings_bulk_upload_empty.xlsx", "application/vnd.ms-excel") } |
|
||||||
|
|
||||||
before do |
|
||||||
allow(Organisation).to receive(:find).with(107_242).and_return(organisation) |
|
||||||
end |
|
||||||
|
|
||||||
context "when a user is not signed in" do |
|
||||||
describe "GET #start" do |
|
||||||
before { get start_bulk_upload_lettings_logs_path, headers:, params: {} } |
|
||||||
|
|
||||||
it "does not let you see the bulk upload page" do |
|
||||||
expect(response).to redirect_to("/account/sign-in") |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
describe "GET #show" do |
|
||||||
before { get url, headers:, params: {} } |
|
||||||
|
|
||||||
it "does not let you see the bulk upload page" do |
|
||||||
expect(response).to redirect_to("/account/sign-in") |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
describe "POST #bulk upload" do |
|
||||||
before { post url, params: { bulk_upload: { lettings_log_bulk_upload: valid_file } } } |
|
||||||
|
|
||||||
it "does not let you submit bulk uploads" do |
|
||||||
expect(response).to redirect_to("/account/sign-in") |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "when a user is signed in" do |
|
||||||
before do |
|
||||||
sign_in user |
|
||||||
end |
|
||||||
|
|
||||||
describe "GET #show" do |
|
||||||
before do |
|
||||||
get url, params: {} |
|
||||||
end |
|
||||||
|
|
||||||
it "returns a success response" do |
|
||||||
expect(response).to be_successful |
|
||||||
end |
|
||||||
|
|
||||||
it "returns a page with a file upload form" do |
|
||||||
expect(response.body).to match(/<input id="legacy-bulk-upload-lettings-log-bulk-upload-field" class="govuk-file-upload"/) |
|
||||||
expect(response.body).to match(/<button type="submit" formnovalidate="formnovalidate" class="govuk-button"/) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
describe "GET #start" do |
|
||||||
before do |
|
||||||
Timecop.freeze(time) |
|
||||||
get start_bulk_upload_lettings_logs_path |
|
||||||
end |
|
||||||
|
|
||||||
after do |
|
||||||
Timecop.unfreeze |
|
||||||
end |
|
||||||
|
|
||||||
context "when not crossover period" do |
|
||||||
let(:time) { Time.utc(2023, 2, 8) } |
|
||||||
|
|
||||||
it "redirects to bulk upload path" do |
|
||||||
expect(request).to redirect_to( |
|
||||||
bulk_upload_lettings_log_path( |
|
||||||
id: "prepare-your-file", |
|
||||||
form: { year: 2022 }, |
|
||||||
), |
|
||||||
) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "when crossover period" do |
|
||||||
let(:time) { Time.utc(2022, 6, 8) } |
|
||||||
|
|
||||||
it "redirects to bulk upload path" do |
|
||||||
expect(request).to redirect_to( |
|
||||||
bulk_upload_lettings_log_path(id: "year"), |
|
||||||
) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
describe "POST #bulk upload" do |
|
||||||
context "with a valid file based on the upload template" do |
|
||||||
let(:request) { post url, params: { bulk_upload: { lettings_log_bulk_upload: valid_file } } } |
|
||||||
|
|
||||||
it "creates lettings logs for each row in the template" do |
|
||||||
expect { request }.to change(LettingsLog, :count).by(9) |
|
||||||
end |
|
||||||
|
|
||||||
it "redirects to the lettings log index page" do |
|
||||||
expect(request).to redirect_to(lettings_logs_path) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "with an invalid file type" do |
|
||||||
before { post url, params: { bulk_upload: { lettings_log_bulk_upload: invalid_file } } } |
|
||||||
|
|
||||||
it "displays an error message" do |
|
||||||
expect(response.body).to match(/Invalid file type/) |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "with an empty file" do |
|
||||||
let(:request) { post url, params: { bulk_upload: { lettings_log_bulk_upload: empty_file } } } |
|
||||||
|
|
||||||
it "displays an error message" do |
|
||||||
request |
|
||||||
expect(response.body).to match(/No data found/) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
Loading…
Reference in new issue