Browse Source
* form handler to return all questions from lettings forms for all years with ordering interleaved functionality and tests * refactor lettings log csv service and all associated tests remove methods on log models when we can call them directly on associated models update job to call the service directly with the collection of logs rather minor modifications to the sales log csv service update many test files to test the appropriate logic in the appropriate place * tidying final amendments to tests remove commented code rename variable * change the position of the rent value check field in the headers * CLDC-2492 add creation method field to logs (#1738) * create migrations to add creation method fields to both log types * add enum definition to logs for creation method * upadte csv export services to retrieve creation method values direct from the log, remove methods previously used from the log model * run migrations to update schema * ensure that logs created via bulk upload have this set correctly when createdCLDC-2492-create-rake-task-to-set-creation-method-for-existing-logs
Arthur Campbell
2 years ago
committed by
GitHub
27 changed files with 562 additions and 828 deletions
@ -0,0 +1,5 @@ |
|||||||
|
class AddCreationMethodToLettingsLogs < ActiveRecord::Migration[7.0] |
||||||
|
def change |
||||||
|
add_column :lettings_logs, :creation_method, :integer, default: 1 |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,5 @@ |
|||||||
|
class AddCreationMethodToSalesLogs < ActiveRecord::Migration[7.0] |
||||||
|
def change |
||||||
|
add_column :sales_logs, :creation_method, :integer, default: 1 |
||||||
|
end |
||||||
|
end |
|
|
|
|
|
|
|
|
|
@ -1,430 +1,227 @@ |
|||||||
require "rails_helper" |
require "rails_helper" |
||||||
|
|
||||||
RSpec.describe Csv::LettingsLogCsvService do |
RSpec.describe Csv::LettingsLogCsvService do |
||||||
context "when the user is support" do |
let(:form_handler_mock) { instance_double(FormHandler) } |
||||||
let(:user) { create(:user, :support) } |
let(:organisation) { create(:organisation) } |
||||||
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } |
let(:fixed_time) { Time.zone.local(2023, 6, 26) } |
||||||
|
let(:log) do |
||||||
|
create( |
||||||
|
:lettings_log, |
||||||
|
:completed, |
||||||
|
startdate: fixed_time, |
||||||
|
created_at: fixed_time, |
||||||
|
updated_at: fixed_time, |
||||||
|
mrcdate: fixed_time - 1.day, |
||||||
|
voiddate: fixed_time - 2.days, |
||||||
|
propcode: "ABCDEFG", |
||||||
|
tenancycode: "HIJKLMN", |
||||||
|
postcode_full: "NW9 5LL", |
||||||
|
ppostcode_full: "TN23 6LZ", |
||||||
|
created_by: user, |
||||||
|
managing_organisation: organisation, |
||||||
|
) |
||||||
|
end |
||||||
|
let(:user) { create(:user, :support, email: "s.port@jeemayle.com") } |
||||||
|
let(:service) { described_class.new(user:, export_type:) } |
||||||
|
let(:export_type) { "labels" } |
||||||
|
let(:csv) { CSV.parse(service.prepare_csv(LettingsLog.where(id: logs.map(&:id)))) } |
||||||
|
let(:logs) { [log] } |
||||||
|
let(:headers) { csv.first } |
||||||
|
|
||||||
|
it "calls the form handler to get all questions in order when initialized" do |
||||||
|
allow(FormHandler).to receive(:instance).and_return(form_handler_mock) |
||||||
|
allow(form_handler_mock).to receive(:ordered_lettings_questions_for_all_years).and_return([]) |
||||||
|
service |
||||||
|
expect(form_handler_mock).to have_received(:ordered_lettings_questions_for_all_years) |
||||||
|
end |
||||||
|
|
||||||
|
it "returns a string" do |
||||||
|
result = service.prepare_csv(LettingsLog.all) |
||||||
|
expect(result).to be_a String |
||||||
|
end |
||||||
|
|
||||||
|
it "returns a csv with headers" do |
||||||
|
expect(csv.first.first).to eq "id" |
||||||
|
end |
||||||
|
|
||||||
|
context "when stubbing :ordered_lettings_questions_for_all_years" do |
||||||
|
let(:lettings_form) do |
||||||
|
FormFactory.new(year: 2050, type: "lettings") |
||||||
|
.with_sections([build(:section, :with_questions, question_ids:, questions:)]) |
||||||
|
.build |
||||||
|
end |
||||||
|
let(:question_ids) { nil } |
||||||
|
let(:questions) { nil } |
||||||
|
|
||||||
before do |
before do |
||||||
LettingsLog.create!(startdate: Time.zone.today, created_at: Time.utc(2022, 2, 8, 16, 52, 15)) |
allow(FormHandler).to receive(:instance).and_return(form_handler_mock) |
||||||
allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form) |
allow(form_handler_mock).to receive(:form_name_from_start_year) |
||||||
|
allow(form_handler_mock).to receive(:get_form).and_return(lettings_form) |
||||||
|
allow(form_handler_mock).to receive(:ordered_lettings_questions_for_all_years).and_return(lettings_form.questions) |
||||||
|
allow(form_handler_mock).to receive(:lettings_in_crossover_period?).and_return false |
||||||
|
end |
||||||
|
|
||||||
|
context "when it returns questions with particular ids" do |
||||||
|
let(:question_ids) { %w[prevten startdate brent rent_type] } |
||||||
|
|
||||||
|
it "includes log attributes related to questions to the headers" do |
||||||
|
expect(headers).to include(*question_ids.first(3)) |
||||||
|
end |
||||||
|
|
||||||
|
it "removes some log attributes related to questions from the headers and replaces them with their derived values in the correct order" do |
||||||
|
expect(headers).not_to include "rent_type" |
||||||
|
expect(headers).to include(*%w[wrent renttype rent_type_detail]) |
||||||
|
end |
||||||
end |
end |
||||||
|
|
||||||
it "sets csv attributes in correct order" do |
context "when it returns checkbox questions" do |
||||||
expected_csv_attributes = %w[ |
let(:questions) do |
||||||
id |
[ |
||||||
status |
build(:question, id: "condition_effects", type: "checkbox", answer_options: { "illness_type_1" => {}, "illness_type_2" => {}, "illness_type_3" => {} }), |
||||||
created_at |
build(:question, id: "letting_allocation", type: "checkbox", answer_options: { "cbl" => {}, "cap" => {}, "chr" => {} }), |
||||||
updated_at |
] |
||||||
created_by_name |
end |
||||||
is_dpo |
|
||||||
owning_organisation_name |
it "does not add the id of the checkbox question to the headers" do |
||||||
managing_organisation_name |
question_ids = questions.map(&:id) |
||||||
collection_start_year |
expect(headers).not_to include(*question_ids) |
||||||
needstype |
end |
||||||
renewal |
|
||||||
startdate |
it "adds the related log attributes from the answer options to the headers" do |
||||||
rent_type_detail |
log_attributes = questions.flat_map { |q| q.answer_options.keys } |
||||||
irproduct_other |
expect(headers).to include(*log_attributes) |
||||||
tenancycode |
end |
||||||
propcode |
|
||||||
postcode_known |
|
||||||
postcode_full |
|
||||||
is_la_inferred |
|
||||||
la_label |
|
||||||
la |
|
||||||
first_time_property_let_as_social_housing |
|
||||||
unitletas |
|
||||||
rsnvac |
|
||||||
offered |
|
||||||
unittype_gn |
|
||||||
builtype |
|
||||||
wchair |
|
||||||
beds |
|
||||||
voiddate |
|
||||||
void_date_value_check |
|
||||||
majorrepairs |
|
||||||
mrcdate |
|
||||||
major_repairs_date_value_check |
|
||||||
startertenancy |
|
||||||
tenancy |
|
||||||
tenancyother |
|
||||||
tenancylength |
|
||||||
sheltered |
|
||||||
declaration |
|
||||||
hhmemb |
|
||||||
pregnancy_value_check |
|
||||||
age1_known |
|
||||||
age1 |
|
||||||
sex1 |
|
||||||
ethnic_group |
|
||||||
ethnic |
|
||||||
national |
|
||||||
ecstat1 |
|
||||||
retirement_value_check |
|
||||||
details_known_2 |
|
||||||
relat2 |
|
||||||
age2_known |
|
||||||
age2 |
|
||||||
sex2 |
|
||||||
ecstat2 |
|
||||||
details_known_3 |
|
||||||
relat3 |
|
||||||
age3_known |
|
||||||
age3 |
|
||||||
sex3 |
|
||||||
ecstat3 |
|
||||||
details_known_4 |
|
||||||
relat4 |
|
||||||
age4_known |
|
||||||
age4 |
|
||||||
sex4 |
|
||||||
ecstat4 |
|
||||||
details_known_5 |
|
||||||
relat5 |
|
||||||
age5_known |
|
||||||
age5 |
|
||||||
sex5 |
|
||||||
ecstat5 |
|
||||||
details_known_6 |
|
||||||
relat6 |
|
||||||
age6_known |
|
||||||
age6 |
|
||||||
sex6 |
|
||||||
ecstat6 |
|
||||||
details_known_7 |
|
||||||
relat7 |
|
||||||
age7_known |
|
||||||
age7 |
|
||||||
sex7 |
|
||||||
ecstat7 |
|
||||||
details_known_8 |
|
||||||
relat8 |
|
||||||
age8_known |
|
||||||
age8 |
|
||||||
sex8 |
|
||||||
ecstat8 |
|
||||||
armedforces |
|
||||||
leftreg |
|
||||||
reservist |
|
||||||
preg_occ |
|
||||||
housingneeds |
|
||||||
housingneeds_type |
|
||||||
housingneeds_other |
|
||||||
illness |
|
||||||
illness_type_4 |
|
||||||
illness_type_5 |
|
||||||
illness_type_2 |
|
||||||
illness_type_6 |
|
||||||
illness_type_7 |
|
||||||
illness_type_3 |
|
||||||
illness_type_9 |
|
||||||
illness_type_8 |
|
||||||
illness_type_1 |
|
||||||
illness_type_10 |
|
||||||
layear |
|
||||||
waityear |
|
||||||
reason |
|
||||||
reasonother |
|
||||||
prevten |
|
||||||
underoccupation_benefitcap |
|
||||||
homeless |
|
||||||
ppcodenk |
|
||||||
ppostcode_full |
|
||||||
previous_la_known |
|
||||||
is_previous_la_inferred |
|
||||||
prevloc_label |
|
||||||
prevloc |
|
||||||
reasonpref |
|
||||||
rp_homeless |
|
||||||
rp_insan_unsat |
|
||||||
rp_medwel |
|
||||||
rp_hardship |
|
||||||
rp_dontknow |
|
||||||
cbl |
|
||||||
cap |
|
||||||
chr |
|
||||||
letting_allocation_unknown |
|
||||||
referral |
|
||||||
net_income_known |
|
||||||
earnings |
|
||||||
incfreq |
|
||||||
net_income_value_check |
|
||||||
hb |
|
||||||
benefits |
|
||||||
household_charge |
|
||||||
period |
|
||||||
is_carehome |
|
||||||
chcharge |
|
||||||
carehome_charges_value_check |
|
||||||
brent |
|
||||||
scharge |
|
||||||
pscharge |
|
||||||
supcharg |
|
||||||
tcharge |
|
||||||
rent_value_check |
|
||||||
hbrentshortfall |
|
||||||
tshortfall_known |
|
||||||
tshortfall |
|
||||||
housingneeds_a |
|
||||||
housingneeds_b |
|
||||||
housingneeds_c |
|
||||||
housingneeds_f |
|
||||||
housingneeds_g |
|
||||||
housingneeds_h |
|
||||||
property_owner_organisation |
|
||||||
property_manager_organisation |
|
||||||
purchaser_code |
|
||||||
property_relet |
|
||||||
incref |
|
||||||
renttype |
|
||||||
lettype |
|
||||||
totchild |
|
||||||
totelder |
|
||||||
totadult |
|
||||||
nocharge |
|
||||||
has_benefits |
|
||||||
wrent |
|
||||||
wscharge |
|
||||||
wpschrge |
|
||||||
wsupchrg |
|
||||||
wtcharge |
|
||||||
wtshortfall |
|
||||||
refused |
|
||||||
wchchrg |
|
||||||
newprop |
|
||||||
old_form_id |
|
||||||
lar |
|
||||||
irproduct |
|
||||||
old_id |
|
||||||
joint |
|
||||||
hhtype |
|
||||||
new_old |
|
||||||
vacdays |
|
||||||
unresolved |
|
||||||
updated_by_id |
|
||||||
uprn |
|
||||||
uprn_known |
|
||||||
uprn_confirmed |
|
||||||
address_line1 |
|
||||||
address_line2 |
|
||||||
town_or_city |
|
||||||
county |
|
||||||
status_cache |
|
||||||
discarded_at |
|
||||||
unittype_sh |
|
||||||
scheme_code |
|
||||||
scheme_service_name |
|
||||||
scheme_sensitive |
|
||||||
scheme_type |
|
||||||
scheme_registered_under_care_act |
|
||||||
scheme_owning_organisation_name |
|
||||||
scheme_primary_client_group |
|
||||||
scheme_has_other_client_group |
|
||||||
scheme_secondary_client_group |
|
||||||
scheme_support_type |
|
||||||
scheme_intended_stay |
|
||||||
scheme_created_at |
|
||||||
location_code |
|
||||||
location_postcode |
|
||||||
location_name |
|
||||||
location_units |
|
||||||
location_type_of_unit |
|
||||||
location_mobility_type |
|
||||||
location_admin_district |
|
||||||
location_startdate |
|
||||||
] |
|
||||||
|
|
||||||
csv = CSV.parse(described_class.new(user, export_type: "labels").to_csv) |
|
||||||
|
|
||||||
expect(csv.first).to eq(expected_csv_attributes) |
|
||||||
end |
end |
||||||
end |
end |
||||||
|
|
||||||
context "when the user is not support" do |
it "adds log attributes not related to questions to the headers" do |
||||||
let(:user) { FactoryBot.create(:user) } |
expect(headers.first(5)).to eq %w[id status created_by is_dpo created_at] |
||||||
let(:real_2021_2022_form) { Form.new("config/forms/2021_2022.json") } |
end |
||||||
|
|
||||||
before do |
it "adds attributes related to associated schemes and locations to the headers" do |
||||||
LettingsLog.create!(startdate: Time.zone.today, created_at: Time.utc(2022, 2, 8, 16, 52, 15)) |
expect(headers).to include(*%w[scheme_service_name scheme_sensitive SCHTYPE scheme_registered_under_care_act]) |
||||||
allow(FormHandler.instance).to receive(:get_form).and_return(real_2021_2022_form) |
expect(headers.last(5)).to eq %w[location_units location_type_of_unit location_mobility_type location_admin_district location_startdate] |
||||||
|
end |
||||||
|
|
||||||
|
context "when there are many logs" do |
||||||
|
let(:logs) { create_list(:lettings_log, log_count) } |
||||||
|
let(:log_count) { 30 } |
||||||
|
|
||||||
|
it "creates a CSV with the correct number of logs" do |
||||||
|
expected_row_count_with_headers = log_count + 1 |
||||||
|
expect(csv.size).to be expected_row_count_with_headers |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when exporting with human readable labels" do |
||||||
|
let(:export_type) { "labels" } |
||||||
|
|
||||||
|
it "gives answer to radio questions as labels" do |
||||||
|
relat2_column_index = csv.first.index("relat2") |
||||||
|
relat2_value = csv.second[relat2_column_index] |
||||||
|
expect(relat2_value).to eq "Partner" |
||||||
|
end |
||||||
|
|
||||||
|
it "gives answers to free input questions as the user input" do |
||||||
|
age1_column_index = csv.first.index("age1") |
||||||
|
age1_value = csv.second[age1_column_index] |
||||||
|
expect(age1_value).to eq 35.to_s |
||||||
end |
end |
||||||
|
|
||||||
it "sets csv attributes in correct order and without omitted values" do |
it "exports the code for the local authority under the heading 'la'" do |
||||||
expected_csv_attributes = %w[ |
la_column_index = csv.first.index("la") |
||||||
id |
la_value = csv.second[la_column_index] |
||||||
status |
expect(la_value).to eq "E09000003" |
||||||
created_at |
end |
||||||
updated_at |
|
||||||
created_by_name |
it "exports the label for the local authority under the heading 'la_label'" do |
||||||
is_dpo |
la_label_column_index = csv.first.index("la_label") |
||||||
owning_organisation_name |
la_label_value = csv.second[la_label_column_index] |
||||||
managing_organisation_name |
expect(la_label_value).to eq "Barnet" |
||||||
collection_start_year |
end |
||||||
renewal |
|
||||||
startdate |
it "exports the CSV with all values correct" do |
||||||
irproduct_other |
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_labels.csv") |
||||||
tenancycode |
values_to_delete = %w[id vacdays] |
||||||
propcode |
values_to_delete.each do |attribute| |
||||||
postcode_full |
index = csv.first.index(attribute) |
||||||
la_label |
csv.second[index] = nil |
||||||
unitletas |
end |
||||||
rsnvac |
expect(csv).to eq expected_content |
||||||
offered |
end |
||||||
unittype_gn |
end |
||||||
builtype |
|
||||||
wchair |
context "when exporting as codes" do |
||||||
beds |
let(:export_type) { "codes" } |
||||||
voiddate |
|
||||||
void_date_value_check |
it "gives answer to radio questions as labels" do |
||||||
majorrepairs |
relat2_column_index = csv.first.index("relat2") |
||||||
mrcdate |
relat2_value = csv.second[relat2_column_index] |
||||||
major_repairs_date_value_check |
expect(relat2_value).to eq "P" |
||||||
startertenancy |
end |
||||||
tenancy |
|
||||||
tenancyother |
it "gives answers to free input questions as the user input" do |
||||||
tenancylength |
age1_column_index = csv.first.index("age1") |
||||||
sheltered |
age1_value = csv.second[age1_column_index] |
||||||
declaration |
expect(age1_value).to eq 35.to_s |
||||||
age1 |
end |
||||||
sex1 |
|
||||||
ethnic_group |
it "exports the code for the local authority under the heading 'la'" do |
||||||
ethnic |
la_column_index = csv.first.index("la") |
||||||
national |
la_value = csv.second[la_column_index] |
||||||
ecstat1 |
expect(la_value).to eq "E09000003" |
||||||
relat2 |
end |
||||||
age2 |
|
||||||
sex2 |
it "exports the label for the local authority under the heading 'la_label'" do |
||||||
ecstat2 |
la_label_column_index = csv.first.index("la_label") |
||||||
relat3 |
la_label_value = csv.second[la_label_column_index] |
||||||
age3 |
expect(la_label_value).to eq "Barnet" |
||||||
sex3 |
end |
||||||
ecstat3 |
|
||||||
relat4 |
it "exports the CSV with all values correct" do |
||||||
age4 |
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_codes.csv") |
||||||
sex4 |
values_to_delete = %w[id vacdays] |
||||||
ecstat4 |
values_to_delete.each do |attribute| |
||||||
relat5 |
index = csv.first.index(attribute) |
||||||
age5 |
csv.second[index] = nil |
||||||
sex5 |
end |
||||||
ecstat5 |
expect(csv).to eq expected_content |
||||||
relat6 |
end |
||||||
age6 |
end |
||||||
sex6 |
|
||||||
ecstat6 |
context "when the user is not a support user" do |
||||||
relat7 |
let(:user) { create(:user, email: "choreographer@owtluk.com") } |
||||||
age7 |
|
||||||
sex7 |
it "does not include certain attributes in the headers" do |
||||||
ecstat7 |
expect(headers).not_to include(*%w[rent_type_detail wrent wscharge wpschrge wsupchrg wtcharge]) |
||||||
relat8 |
end |
||||||
age8 |
|
||||||
sex8 |
context "and exporting with labels" do |
||||||
ecstat8 |
let(:export_type) { "labels" } |
||||||
armedforces |
|
||||||
leftreg |
it "exports the CSV with all values correct" do |
||||||
reservist |
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_labels.csv") |
||||||
preg_occ |
values_to_delete = %w[id] |
||||||
housingneeds |
values_to_delete.each do |attribute| |
||||||
housingneeds_type |
index = csv.first.index(attribute) |
||||||
housingneeds_other |
csv.second[index] = nil |
||||||
illness |
end |
||||||
illness_type_4 |
expect(csv).to eq expected_content |
||||||
illness_type_5 |
end |
||||||
illness_type_2 |
end |
||||||
illness_type_6 |
|
||||||
illness_type_7 |
context "and exporting values as codes" do |
||||||
illness_type_3 |
let(:export_type) { "codes" } |
||||||
illness_type_9 |
|
||||||
illness_type_8 |
it "exports the CSV with all values correct" do |
||||||
illness_type_1 |
expected_content = CSV.read("spec/fixtures/files/lettings_log_csv_export_non_support_codes.csv") |
||||||
illness_type_10 |
values_to_delete = %w[id] |
||||||
layear |
values_to_delete.each do |attribute| |
||||||
waityear |
index = csv.first.index(attribute) |
||||||
reason |
csv.second[index] = nil |
||||||
reasonother |
end |
||||||
prevten |
expect(csv).to eq expected_content |
||||||
underoccupation_benefitcap |
end |
||||||
homeless |
|
||||||
ppcodenk |
|
||||||
ppostcode_full |
|
||||||
prevloc_label |
|
||||||
reasonpref |
|
||||||
rp_homeless |
|
||||||
rp_insan_unsat |
|
||||||
rp_medwel |
|
||||||
rp_hardship |
|
||||||
rp_dontknow |
|
||||||
cbl |
|
||||||
cap |
|
||||||
chr |
|
||||||
referral |
|
||||||
earnings |
|
||||||
incfreq |
|
||||||
hb |
|
||||||
benefits |
|
||||||
household_charge |
|
||||||
period |
|
||||||
chcharge |
|
||||||
carehome_charges_value_check |
|
||||||
brent |
|
||||||
scharge |
|
||||||
pscharge |
|
||||||
supcharg |
|
||||||
tcharge |
|
||||||
hbrentshortfall |
|
||||||
tshortfall |
|
||||||
housingneeds_a |
|
||||||
housingneeds_b |
|
||||||
housingneeds_c |
|
||||||
housingneeds_f |
|
||||||
housingneeds_g |
|
||||||
housingneeds_h |
|
||||||
property_owner_organisation |
|
||||||
property_manager_organisation |
|
||||||
purchaser_code |
|
||||||
property_relet |
|
||||||
incref |
|
||||||
lettype |
|
||||||
nocharge |
|
||||||
has_benefits |
|
||||||
refused |
|
||||||
wchchrg |
|
||||||
newprop |
|
||||||
lar |
|
||||||
irproduct |
|
||||||
joint |
|
||||||
uprn |
|
||||||
uprn_known |
|
||||||
address_line1 |
|
||||||
address_line2 |
|
||||||
town_or_city |
|
||||||
county |
|
||||||
unittype_sh |
|
||||||
scheme_code |
|
||||||
scheme_service_name |
|
||||||
scheme_sensitive |
|
||||||
scheme_type |
|
||||||
scheme_registered_under_care_act |
|
||||||
scheme_owning_organisation_name |
|
||||||
scheme_primary_client_group |
|
||||||
scheme_has_other_client_group |
|
||||||
scheme_secondary_client_group |
|
||||||
scheme_support_type |
|
||||||
scheme_intended_stay |
|
||||||
scheme_created_at |
|
||||||
location_code |
|
||||||
location_postcode |
|
||||||
location_name |
|
||||||
location_units |
|
||||||
location_type_of_unit |
|
||||||
location_mobility_type |
|
||||||
location_admin_district |
|
||||||
location_startdate |
|
||||||
] |
|
||||||
|
|
||||||
csv = CSV.parse(described_class.new(user, export_type: "labels").to_csv) |
|
||||||
|
|
||||||
expect(csv.first).to eq(expected_csv_attributes) |
|
||||||
end |
end |
||||||
end |
end |
||||||
end |
end |
||||||
|
Loading…
Reference in new issue