Browse Source

Merge branch 'main' into CLDC-1528-person-1-relationship-to-buyer-1

# Conflicts:
#	db/schema.rb
CLDC-1528-person-1-relationship-to-buyer-1
natdeanlewissoftwire 2 years ago
parent
commit
ed2afc16fb
  1. 6
      Gemfile.lock
  2. 115
      app/controllers/organisation_relationships_controller.rb
  3. 2
      app/helpers/tasklist_helper.rb
  4. 21
      app/models/form/sales/pages/buyer1_income_value_check.rb
  5. 21
      app/models/form/sales/pages/mortgage_value_check.rb
  6. 1
      app/models/form/sales/questions/buyer1_income.rb
  7. 25
      app/models/form/sales/questions/buyer1_income_value_check.rb
  8. 25
      app/models/form/sales/questions/mortgage_value_check.rb
  9. 2
      app/models/form/sales/subsections/income_benefits_and_savings.rb
  10. 13
      app/models/organisation_relationship.rb
  11. 51
      app/models/sales_log.rb
  12. 14
      app/models/validations/sales/financial_validations.rb
  13. 23
      app/models/validations/sales/soft_validations.rb
  14. 2
      app/views/devise/unlocks/new.html.erb
  15. 2
      app/views/organisation_relationships/_related_organisation_select_question.html.erb
  16. 3
      app/views/organisation_relationships/add_housing_provider.html.erb
  17. 3
      app/views/organisation_relationships/add_managing_agent.html.erb
  18. 2
      app/views/organisation_relationships/managing_agents.html.erb
  19. 9
      config/locales/en.yml
  20. 6
      db/migrate/20221212161657_add_details_known1_to_sales_log.rb
  21. 10
      db/migrate/20221213085819_add_mortgage_and_value_checks.rb
  22. 9
      db/schema.rb
  23. 2
      spec/factories/sales_log.rb
  24. 33
      spec/models/form/sales/pages/buyer1_income_value_check_spec.rb
  25. 33
      spec/models/form/sales/pages/mortgage_value_check_spec.rb
  26. 4
      spec/models/form/sales/questions/buyer1_income_spec.rb
  27. 61
      spec/models/form/sales/questions/buyer1_income_value_check_spec.rb
  28. 61
      spec/models/form/sales/questions/mortgage_value_check_spec.rb
  29. 2
      spec/models/form/sales/subsections/income_benefits_and_savings_spec.rb
  30. 56
      spec/models/validations/sales/financial_validations_spec.rb
  31. 204
      spec/models/validations/sales/soft_validations_spec.rb
  32. 16
      spec/requests/organisation_relationships_controller_spec.rb

6
Gemfile.lock

@ -199,7 +199,7 @@ GEM
listen (3.7.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
loofah (2.19.0)
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
@ -294,8 +294,8 @@ GEM
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
rails-html-sanitizer (1.4.4)
loofah (~> 2.19, >= 2.19.1)
railties (7.0.4)
actionpack (= 7.0.4)
activesupport (= 7.0.4)

115
app/controllers/organisation_relationships_controller.rb

@ -5,13 +5,19 @@ class OrganisationRelationshipsController < ApplicationController
before_action :authenticate_user!
before_action :authenticate_scope!
before_action :organisations
before_action :target_organisation, only: %i[
remove_housing_provider
remove_managing_agent
delete_housing_provider
delete_managing_agent
]
def housing_providers
housing_providers = organisation.housing_providers
unpaginated_filtered_housing_providers = filtered_collection(housing_providers, search_term)
organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name)
respond_to :html
@pagy, @housing_providers = pagy(unpaginated_filtered_housing_providers)
@organisations = organisations
@searched = search_term.presence
@total_count = housing_providers.size
end
@ -19,107 +25,84 @@ class OrganisationRelationshipsController < ApplicationController
def managing_agents
managing_agents = organisation.managing_agents
unpaginated_filtered_managing_agents = filtered_collection(managing_agents, search_term)
organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name)
respond_to :html
@pagy, @managing_agents = pagy(unpaginated_filtered_managing_agents)
@organisations = organisations
@searched = search_term.presence
@total_count = managing_agents.size
end
def add_housing_provider
@organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name)
respond_to :html
@organisation_relationship = organisation.parent_organisation_relationships.new
end
def add_managing_agent
@organisations = Organisation.where.not(id: @organisation.id).pluck(:id, :name)
respond_to :html
@organisation_relationship = organisation.child_organisation_relationships.new
end
def create_housing_provider
child_organisation = @organisation
if params[:organisation][:related_organisation_id].empty?
@organisation.errors.add :related_organisation_id, "You must choose a housing provider"
@organisations = Organisation.where.not(id: child_organisation.id).pluck(:id, :name)
render "organisation_relationships/add_housing_provider"
return
@organisation_relationship = organisation.parent_organisation_relationships.new(organisation_relationship_params)
if @organisation_relationship.save(context: :housing_provider)
flash[:notice] = "#{@organisation_relationship.parent_organisation.name} is now one of #{current_user.data_coordinator? ? 'your' : "this organisation's"} housing providers"
redirect_to housing_providers_organisation_path
else
parent_organisation = related_organisation
if OrganisationRelationship.exists?(child_organisation:, parent_organisation:)
@organisation.errors.add :related_organisation_id, "You have already added this housing provider"
@organisations = Organisation.where.not(id: child_organisation.id).pluck(:id, :name)
render "organisation_relationships/add_housing_provider"
return
end
@organisations = Organisation.where.not(id: organisation.id).pluck(:id, :name)
render "organisation_relationships/add_housing_provider", status: :unprocessable_entity
end
create!(child_organisation:, parent_organisation:)
flash[:notice] = "#{related_organisation.name} is now one of #{current_user.data_coordinator? ? 'your' : "this organisation's"} housing providers"
redirect_to housing_providers_organisation_path
end
def create_managing_agent
parent_organisation = @organisation
if params[:organisation][:related_organisation_id].empty?
@organisation.errors.add :related_organisation_id, "You must choose a managing agent"
@organisations = Organisation.where.not(id: parent_organisation.id).pluck(:id, :name)
render "organisation_relationships/add_managing_agent"
return
@organisation_relationship = organisation.child_organisation_relationships.new(organisation_relationship_params)
if @organisation_relationship.save
flash[:notice] = "#{@organisation_relationship.child_organisation.name} is now one of #{current_user.data_coordinator? ? 'your' : "this organisation's"} managing agents"
redirect_to managing_agents_organisation_path
else
child_organisation = related_organisation
if OrganisationRelationship.exists?(child_organisation:, parent_organisation:)
@organisation.errors.add :related_organisation_id, "You have already added this managing agent"
@organisations = Organisation.where.not(id: parent_organisation.id).pluck(:id, :name)
render "organisation_relationships/add_managing_agent"
return
end
@organisations = Organisation.where.not(id: organisation.id).pluck(:id, :name)
render "organisation_relationships/add_managing_agent", status: :unprocessable_entity
end
create!(child_organisation:, parent_organisation:)
flash[:notice] = "#{related_organisation.name} is now one of #{current_user.data_coordinator? ? 'your' : "this organisation's"} managing agents"
redirect_to managing_agents_organisation_path
end
def remove_housing_provider
@target_organisation_id = target_organisation.id
end
def remove_housing_provider; end
def delete_housing_provider
relationship = OrganisationRelationship.find_by!(
child_organisation: @organisation,
OrganisationRelationship.find_by!(
child_organisation: organisation,
parent_organisation: target_organisation,
)
relationship.destroy!
).destroy!
flash[:notice] = "#{target_organisation.name} is no longer one of #{current_user.data_coordinator? ? 'your' : "this organisation's"} housing providers"
redirect_to housing_providers_organisation_path
end
def remove_managing_agent
@target_organisation_id = target_organisation.id
end
def remove_managing_agent; end
def delete_managing_agent
relationship = OrganisationRelationship.find_by!(
parent_organisation: @organisation,
OrganisationRelationship.find_by!(
parent_organisation: organisation,
child_organisation: target_organisation,
)
relationship.destroy!
).destroy!
flash[:notice] = "#{target_organisation.name} is no longer one of #{current_user.data_coordinator? ? 'your' : "this organisation's"} managing agents"
redirect_to managing_agents_organisation_path
end
private
def create!(child_organisation:, parent_organisation:)
@resource = OrganisationRelationship.new(child_organisation:, parent_organisation:)
@resource.save!
def organisation
@organisation ||= if current_user.support?
Organisation.find(params[:id])
else
current_user.organisation
end
end
def organisation
@organisation ||= Organisation.find(params[:id])
def organisations
@organisations ||= Organisation.where.not(id: organisation.id).pluck(:id, :name)
end
def parent_organisation
@parent_organisation ||= Organisation.find(params[:organisation_relationship][:parent_organisation_id])
end
def related_organisation
@related_organisation ||= Organisation.find(params[:organisation][:related_organisation_id])
def child_organisation
@child_organisation ||= Organisation.find(params[:organisation_relationship][:child_organisation_id])
end
def target_organisation
@ -130,8 +113,12 @@ private
params["search"]
end
def organisation_relationship_params
params.require(:organisation_relationship).permit(:parent_organisation_id, :child_organisation_id)
end
def authenticate_scope!
if current_user.organisation != organisation && !current_user.support?
if current_user.organisation != Organisation.find(params[:id]) && !current_user.support?
render_not_found
end
end

2
app/helpers/tasklist_helper.rb

@ -39,7 +39,7 @@ module TasklistHelper
def review_log_text(log)
if log.collection_period_open?
"You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(log)} until #{(log.form.end_date).to_formatted_s(:govuk_date)}.".html_safe
"You can #{govuk_link_to 'review and make changes to this log', review_lettings_log_path(log)} until #{log.form.end_date.to_formatted_s(:govuk_date)}.".html_safe
else
"This log is from the #{log.form.start_date.year}/#{log.form.start_date.year + 1} collection window, which is now closed."
end

21
app/models/form/sales/pages/buyer1_income_value_check.rb

@ -0,0 +1,21 @@
class Form::Sales::Pages::Buyer1IncomeValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "buyer_1_income_value_check"
@header = ""
@description = ""
@subsection = subsection
@depends_on = [
{
"income1_under_soft_min?" => true,
},
]
@informative_text = {}
end
def questions
@questions ||= [
Form::Sales::Questions::Buyer1IncomeValueCheck.new(nil, nil, self),
]
end
end

21
app/models/form/sales/pages/mortgage_value_check.rb

@ -0,0 +1,21 @@
class Form::Sales::Pages::MortgageValueCheck < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "mortgage_value_check"
@header = ""
@description = ""
@subsection = subsection
@depends_on = [
{
"mortgage_over_soft_max?" => true,
},
]
@informative_text = {}
end
def questions
@questions ||= [
Form::Sales::Questions::MortgageValueCheck.new(nil, nil, self),
]
end
end

1
app/models/form/sales/questions/buyer1_income.rb

@ -7,6 +7,7 @@ class Form::Sales::Questions::Buyer1Income < ::Form::Question
@type = "numeric"
@page = page
@min = 0
@max = 999_999
@step = 1
@width = 5
@prefix = "£"

25
app/models/form/sales/questions/buyer1_income_value_check.rb

@ -0,0 +1,25 @@
class Form::Sales::Questions::Buyer1IncomeValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "income1_value_check"
@check_answer_label = "Income confirmation"
@header = "Are you sure this income is correct?"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}
@hidden_in_check_answers = {
"depends_on" => [
{
"income1_value_check" => 0,
},
{
"income1_value_check" => 1,
},
],
}
@check_answers_card_number = 1
@page = page
end
end

25
app/models/form/sales/questions/mortgage_value_check.rb

@ -0,0 +1,25 @@
class Form::Sales::Questions::MortgageValueCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "mortgage_value_check"
@check_answer_label = "Mortgage confirmation"
@header = "Are you sure that the mortgage is more than 5 times the income used for the mortgage application?"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}
@hidden_in_check_answers = {
"depends_on" => [
{
"mortgage_value_check" => 0,
},
{
"mortgage_value_check" => 1,
},
],
}
@check_answers_card_number = 1
@page = page
end
end

2
app/models/form/sales/subsections/income_benefits_and_savings.rb

@ -10,8 +10,10 @@ class Form::Sales::Subsections::IncomeBenefitsAndSavings < ::Form::Subsection
def pages
@pages ||= [
Form::Sales::Pages::Buyer1Income.new(nil, nil, self),
Form::Sales::Pages::Buyer1IncomeValueCheck.new(nil, nil, self),
Form::Sales::Pages::Buyer1Mortgage.new(nil, nil, self),
Form::Sales::Pages::Buyer2Income.new(nil, nil, self),
Form::Sales::Pages::MortgageValueCheck.new(nil, nil, self),
Form::Sales::Pages::Savings.new(nil, nil, self),
Form::Sales::Pages::PreviousOwnership.new(nil, nil, self),
]

13
app/models/organisation_relationship.rb

@ -1,4 +1,17 @@
class OrganisationRelationship < ApplicationRecord
belongs_to :child_organisation, class_name: "Organisation"
belongs_to :parent_organisation, class_name: "Organisation"
validates :parent_organisation_id, presence: { message: I18n.t("validations.organisation.housing_provider.blank") }
validates :child_organisation_id, presence: { message: I18n.t("validations.organisation.managing_agent.blank") }
validates :parent_organisation_id, uniqueness: { scope: :child_organisation_id, message: I18n.t("validations.organisation.housing_provider.already_added") }
validates :child_organisation_id, uniqueness: { scope: :parent_organisation_id, message: I18n.t("validations.organisation.managing_agent.already_added") }
validate :validate_housing_provider_owns_stock, on: :housing_provider
private
def validate_housing_provider_owns_stock
if parent_organisation_id.present? && !parent_organisation.holds_own_stock
errors.add :parent_organisation_id, I18n.t("validations.organisation.housing_provider.does_not_own_stock")
end
end
end

51
app/models/sales_log.rb

@ -1,5 +1,7 @@
class SalesLogValidator < ActiveModel::Validator
include Validations::Sales::HouseholdValidations
include Validations::SharedValidations
include Validations::Sales::FinancialValidations
def validate(record)
validation_methods = public_methods.select { |method| method.starts_with?("validate_") }
@ -9,6 +11,7 @@ end
class SalesLog < Log
include DerivedVariables::SalesLogVariables
include Validations::Sales::SoftValidations
self.inheritance_column = :_type_disabled
@ -60,4 +63,52 @@ class SalesLog < Log
def unresolved
false
end
LONDON_BOROUGHS = %w[
E09000001
E09000033
E09000020
E09000013
E09000032
E09000022
E09000028
E09000030
E09000012
E09000019
E09000007
E09000005
E09000009
E09000018
E09000027
E09000021
E09000024
E09000029
E09000008
E09000006
E09000023
E09000011
E09000004
E09000016
E09000002
E09000026
E09000025
E09000031
E09000014
E09000010
E09000003
E09000015
E09000017
].freeze
def london_property?
la && LONDON_BOROUGHS.include?(la)
end
def income1_used_for_mortgage?
inc1mort == 1
end
def income2_used_for_mortgage?
inc2mort == 1
end
end

14
app/models/validations/sales/financial_validations.rb

@ -0,0 +1,14 @@
module Validations::Sales::FinancialValidations
# Validations methods need to be called 'validate_<page_name>' to run on model save
# or 'validate_' to run on submit as well
def validate_income1(record)
if record.ecstat1 && record.income1 && record.ownershipsch == 1
if record.london_property?
record.errors.add :income1, I18n.t("validations.financial.income1.over_hard_max", hard_max: 90_000) if record.income1 > 90_000
elsif record.income1 > 80_000
record.errors.add :income1, I18n.t("validations.financial.income1.over_hard_max", hard_max: 80_000)
end
end
end
end

23
app/models/validations/sales/soft_validations.rb

@ -0,0 +1,23 @@
module Validations::Sales::SoftValidations
ALLOWED_INCOME_RANGES = {
1 => OpenStruct.new(soft_min: 5000),
2 => OpenStruct.new(soft_min: 1500),
3 => OpenStruct.new(soft_min: 1000),
5 => OpenStruct.new(soft_min: 2000),
0 => OpenStruct.new(soft_min: 2000),
}.freeze
def income1_under_soft_min?
return false unless ecstat1 && income1 && ALLOWED_INCOME_RANGES[ecstat1]
income1 < ALLOWED_INCOME_RANGES[ecstat1][:soft_min]
end
def mortgage_over_soft_max?
return false unless mortgage && inc1mort && inc2mort
return false if income1_used_for_mortgage? && income1.blank? || income2_used_for_mortgage? && income2.blank?
income_used_for_mortgage = (income1_used_for_mortgage? ? income1 : 0) + (income2_used_for_mortgage? ? income2 : 0)
mortgage > income_used_for_mortgage * 5
end
end

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

@ -1,7 +1,7 @@
<h2>Resend unlock instructions</h2>
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<%= render "devise/shared/error_messages", resource: %>
<%= f.govuk_email_field :email,
label: { text: "Email address" },

2
app/views/organisation_relationships/_related_organisation_select_question.html.erb

@ -1,3 +1,3 @@
<% answers = question.answer_options.map { |key, value| OpenStruct.new(id: key, name: value) } %>
<%= f.govuk_collection_select :related_organisation_id, answers, :id, :name, label: { hidden: true }, "data-controller": "accessible-autocomplete" do %>
<%= f.govuk_collection_select field, answers, :id, :name, label: { hidden: true }, "data-controller": "accessible-autocomplete" do %>
<% end %>

3
app/views/organisation_relationships/add_housing_provider.html.erb

@ -1,4 +1,4 @@
<%= form_with model: @organisation, url: housing_providers_organisation_path, method: "post", local: true do |f| %>
<%= form_with model: @organisation_relationship, url: housing_providers_organisation_path, method: "post", local: true do |f| %>
<% if current_user.support? %>
<%= render partial: "organisations/headings", locals: { main: @organisation.name, sub: nil } %>
<%= render SubNavigationComponent.new(items: secondary_items(request.path, @organisation.id)) %>
@ -18,6 +18,7 @@
<% answer_options[organisation[0]] = organisation[1] %>
<% end %>
<%= render partial: "organisation_relationships/related_organisation_select_question", locals: {
field: :parent_organisation_id,
question: Form::Question.new("", { "answer_options" => answer_options }, nil),
f:,
} %>

3
app/views/organisation_relationships/add_managing_agent.html.erb

@ -1,4 +1,4 @@
<%= form_with model: @organisation, url: managing_agents_organisation_path, method: "post", local: true do |f| %>
<%= form_with model: @organisation_relationship, url: managing_agents_organisation_path, method: "post", local: true do |f| %>
<% if current_user.support? %>
<%= render partial: "organisations/headings", locals: { main: @organisation.name, sub: nil } %>
<%= render SubNavigationComponent.new(items: secondary_items(request.path, @organisation.id)) %>
@ -18,6 +18,7 @@
<% answer_options[organisation[0]] = organisation[1] %>
<% end %>
<%= render partial: "organisation_relationships/related_organisation_select_question", locals: {
field: :child_organisation_id,
question: Form::Question.new("", { "answer_options" => answer_options }, nil),
f:,
} %>

2
app/views/organisation_relationships/managing_agents.html.erb

@ -11,7 +11,7 @@
<p class="govuk-body">This organisation does not currently have any managing agents.</p>
<% end %>
<% else %>
<%= render partial: "organisations/headings", locals: { main: "This organisation managing agents", sub: current_user.organisation.name } %>
<%= render partial: "organisations/headings", locals: { main: "Your managing agents", sub: current_user.organisation.name } %>
<p class="govuk-body">A managing agent can submit logs for this organisation.</p>
<% if @total_count == 0 %>
<p class="govuk-body">This organisation does not currently have any managing agents.</p>

9
config/locales/en.yml

@ -116,6 +116,13 @@ en:
organisation:
name_missing: "Enter the name of the organisation"
provider_type_missing: "Select the organisation type"
housing_provider:
blank: "You must choose a stock owner"
already_added: "You have already added this stock owner"
does_not_own_stock: "You can only add stock owners who own stock, which this organisation does not."
managing_agent:
blank: "You must choose a managing agent"
already_added: "You have already added this managing agent"
not_answered: "You must answer %{question}"
other_field_missing: "If %{main_field_label} is other then %{other_field_label} must be provided"
@ -194,6 +201,8 @@ en:
under_hard_min: "Net income cannot be less than £%{hard_min} per week given the tenant’s working situation"
freq_missing: "Select how often the household receives income"
earnings_missing: "Enter how much income the household has in total"
income1:
over_hard_max: "Income must be lower than £%{hard_max}"
negative_currency: "Enter an amount above 0"
rent:
less_than_shortfall: "Enter an amount that is more than the shortfall in basic rent"

6
db/migrate/20221212161657_add_details_known1_to_sales_log.rb

@ -1,5 +1,7 @@
class AddDetailsKnown1ToSalesLog < ActiveRecord::Migration[7.0]
change_table :sales_logs, bulk: true do |t|
t.column :details_known_1, :integer
def change
change_table :sales_logs, bulk: true do |t|
t.column :details_known_1, :integer
end
end
end

10
db/migrate/20221213085819_add_mortgage_and_value_checks.rb

@ -0,0 +1,10 @@
class AddMortgageAndValueChecks < ActiveRecord::Migration[7.0]
def change
change_table :sales_logs, bulk: true do |t|
t.column :income1_value_check, :integer
t.column :mortgage, :integer
t.column :inc2mort, :integer
t.column :mortgage_value_check, :integer
end
end
end

9
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: 2022_12_13_130736) do
ActiveRecord::Schema[7.0].define(version: 2022_12_13_085819) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -399,12 +399,15 @@ ActiveRecord::Schema[7.0].define(version: 2022_12_13_130736) do
t.integer "inc1mort"
t.integer "income2"
t.integer "income2nk"
t.integer "prevown"
t.integer "savingsnk"
t.integer "savings"
t.integer "prevown"
t.string "sex3"
t.integer "details_known_1"
t.string "relat3"
t.integer "income1_value_check"
t.integer "mortgage"
t.integer "inc2mort"
t.integer "mortgage_value_check"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"
t.index ["managing_organisation_id"], name: "index_sales_logs_on_managing_organisation_id"
t.index ["owning_organisation_id"], name: "index_sales_logs_on_owning_organisation_id"

2
spec/factories/sales_log.rb

@ -57,11 +57,13 @@ FactoryBot.define do
inc1mort { 1 }
income2nk { 0 }
income2 { 10_000 }
inc2mort { 1 }
la_known { "1" }
la { "E09000003" }
savingsnk { 1 }
prevown { 1 }
sex3 { "X" }
mortgage { 20_000 }
end
end
end

33
spec/models/form/sales/pages/buyer1_income_value_check_spec.rb

@ -0,0 +1,33 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::Buyer1IncomeValueCheck, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[income1_value_check])
end
it "has the correct id" do
expect(page.id).to eq("buyer_1_income_value_check")
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"income1_under_soft_min?" => true,
},
])
end
end

33
spec/models/form/sales/pages/mortgage_value_check_spec.rb

@ -0,0 +1,33 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::MortgageValueCheck, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { nil }
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end
it "has correct questions" do
expect(page.questions.map(&:id)).to eq(%w[mortgage_value_check])
end
it "has the correct id" do
expect(page.id).to eq("mortgage_value_check")
end
it "has the correct header" do
expect(page.header).to eq("")
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"mortgage_over_soft_max?" => true,
},
])
end
end

4
spec/models/form/sales/questions/buyer1_income_spec.rb

@ -54,4 +54,8 @@ RSpec.describe Form::Sales::Questions::Buyer1Income, type: :model do
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has correct max" do
expect(question.max).to eq(999_999)
end
end

61
spec/models/form/sales/questions/buyer1_income_value_check_spec.rb

@ -0,0 +1,61 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::Buyer1IncomeValueCheck, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("income1_value_check")
end
it "has the correct header" do
expect(question.header).to eq("Are you sure this income is correct?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Income confirmation")
end
it "has the correct type" do
expect(question.type).to eq("interruption_screen")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
it "has a correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
})
end
it "has the correct hidden_in_check_answers" do
expect(question.hidden_in_check_answers).to eq({
"depends_on" => [
{
"income1_value_check" => 0,
},
{
"income1_value_check" => 1,
},
],
})
end
end

61
spec/models/form/sales/questions/mortgage_value_check_spec.rb

@ -0,0 +1,61 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::MortgageValueCheck, type: :model do
subject(:question) { described_class.new(question_id, question_definition, page) }
let(:question_id) { nil }
let(:question_definition) { nil }
let(:page) { instance_double(Form::Page) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("mortgage_value_check")
end
it "has the correct header" do
expect(question.header).to eq("Are you sure that the mortgage is more than 5 times the income used for the mortgage application?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Mortgage confirmation")
end
it "has the correct type" do
expect(question.type).to eq("interruption_screen")
end
it "is not marked as derived" do
expect(question.derived?).to be false
end
it "has the correct hint" do
expect(question.hint_text).to be_nil
end
it "has a correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
})
end
it "has the correct hidden_in_check_answers" do
expect(question.hidden_in_check_answers).to eq({
"depends_on" => [
{
"mortgage_value_check" => 0,
},
{
"mortgage_value_check" => 1,
},
],
})
end
end

2
spec/models/form/sales/subsections/income_benefits_and_savings_spec.rb

@ -15,8 +15,10 @@ RSpec.describe Form::Sales::Subsections::IncomeBenefitsAndSavings, type: :model
expect(subsection.pages.map(&:id)).to eq(
%w[
buyer_1_income
buyer_1_income_value_check
buyer_1_mortgage
buyer_2_income
mortgage_value_check
savings
previous_ownership
],

56
spec/models/validations/sales/financial_validations_spec.rb

@ -0,0 +1,56 @@
require "rails_helper"
RSpec.describe Validations::Sales::FinancialValidations do
subject(:financial_validator) { validator_class.new }
let(:validator_class) { Class.new { include Validations::Sales::FinancialValidations } }
describe "income validations" do
let(:record) { FactoryBot.create(:sales_log, ownershipsch: 1) }
context "with shared ownership" do
context "and non london borough" do
(0..8).each do |ecstat|
it "adds an error when buyer 1 income is over hard max for ecstat #{ecstat}" do
record.income1 = 85_000
record.ecstat1 = ecstat
financial_validator.validate_income1(record)
expect(record.errors["income1"])
.to include(match I18n.t("validations.financial.income1.over_hard_max", hard_max: 80_000))
end
end
it "validates that the income is within the expected range for the tenant’s employment status" do
record.income1 = 75_000
record.ecstat1 = 1
financial_validator.validate_income1(record)
expect(record.errors["income1"]).to be_empty
end
end
context "and a london borough" do
before do
record.update!(la: "E09000030")
record.reload
end
(0..8).each do |ecstat|
it "adds an error when buyer 1 income is over hard max for ecstat #{ecstat}" do
record.income1 = 95_000
record.ecstat1 = ecstat
financial_validator.validate_income1(record)
expect(record.errors["income1"])
.to include(match I18n.t("validations.financial.income1.over_hard_max", hard_max: 90_000))
end
end
it "validates that the income is within the expected range for the tenant’s employment status" do
record.income1 = 85_000
record.ecstat1 = 1
financial_validator.validate_income1(record)
expect(record.errors["income1"]).to be_empty
end
end
end
end
end

204
spec/models/validations/sales/soft_validations_spec.rb

@ -0,0 +1,204 @@
require "rails_helper"
RSpec.describe Validations::Sales::SoftValidations do
let(:record) { FactoryBot.create(:sales_log) }
describe "income1 min validations" do
context "when validating soft min" do
it "returns false if no income1 is given" do
record.income1 = nil
expect(record)
.not_to be_income1_under_soft_min
end
it "returns false if no ecstat1 is given" do
record.ecstat1 = nil
expect(record)
.not_to be_income1_under_soft_min
end
[
{
income1: 4500,
ecstat1: 1,
},
{
income1: 1400,
ecstat1: 2,
},
{
income1: 999,
ecstat1: 3,
},
{
income1: 1899,
ecstat1: 5,
},
{
income1: 1888,
ecstat1: 0,
},
].each do |test_case|
it "returns true if income1 is below soft min for ecstat1 #{test_case[:ecstat1]}" do
record.income1 = test_case[:income1]
record.ecstat1 = test_case[:ecstat1]
expect(record)
.to be_income1_under_soft_min
end
end
[
{
income1: 5001,
ecstat1: 1,
},
{
income1: 1600,
ecstat1: 2,
},
{
income1: 1004,
ecstat1: 3,
},
{
income1: 2899,
ecstat1: 4,
},
{
income1: 2899,
ecstat1: 5,
},
{
income1: 5,
ecstat1: 6,
},
{
income1: 10_888,
ecstat1: 0,
},
].each do |test_case|
it "returns false if income1 is over soft min for ecstat1 #{test_case[:ecstat1]}" do
record.income1 = test_case[:income1]
record.ecstat1 = test_case[:ecstat1]
expect(record)
.not_to be_income1_under_soft_min
end
end
end
end
describe "mortgage amount validations" do
context "when validating soft max" do
it "returns false if no mortgage is given" do
record.mortgage = nil
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns false if no inc1mort is given" do
record.inc1mort = nil
record.mortgage = 20_000
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns false if no inc2mort is given" do
record.inc1mort = 2
record.inc2mort = nil
record.mortgage = 20_000
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns false if no income1 is given and inc1mort is yes" do
record.inc1mort = 1
record.inc2mort = 2
record.income1 = nil
record.mortgage = 20_000
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns false if no income2 is given and inc2mort is yes" do
record.inc1mort = 2
record.inc2mort = 1
record.income2 = nil
record.mortgage = 20_000
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns true if only income1 is used for morgage and it is less than 1/5 of the morgage" do
record.inc1mort = 1
record.income1 = 10_000
record.mortgage = 51_000
record.inc2mort = 2
expect(record)
.to be_mortgage_over_soft_max
end
it "returns false if only income1 is used for morgage and it is more than 1/5 of the morgage" do
record.inc1mort = 1
record.income1 = 10_000
record.mortgage = 44_000
record.inc2mort = 2
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns true if only income2 is used for morgage and it is less than 1/5 of the morgage" do
record.inc1mort = 2
record.inc2mort = 1
record.income2 = 10_000
record.mortgage = 51_000
expect(record)
.to be_mortgage_over_soft_max
end
it "returns false if only income2 is used for morgage and it is more than 1/5 of the morgage" do
record.inc1mort = 2
record.inc2mort = 1
record.income2 = 10_000
record.mortgage = 44_000
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns true if income1 and income2 are used for morgage and their sum is less than 1/5 of the morgage" do
record.inc1mort = 1
record.inc2mort = 1
record.income1 = 10_000
record.income2 = 10_000
record.mortgage = 101_000
expect(record)
.to be_mortgage_over_soft_max
end
it "returns false if income1 and income2 are used for morgage and their sum is more than 1/5 of the morgage" do
record.inc1mort = 1
record.inc2mort = 1
record.income1 = 8_000
record.income2 = 17_000
record.mortgage = 124_000
expect(record)
.not_to be_mortgage_over_soft_max
end
it "returns true if neither of the incomes are used for morgage and the morgage is more than 0" do
record.inc1mort = 2
record.inc2mort = 2
record.mortgage = 124_000
expect(record)
.to be_mortgage_over_soft_max
end
it "returns true if neither of the incomes are used for morgage and the morgage is 0" do
record.inc1mort = 2
record.inc2mort = 2
record.mortgage = 0
expect(record)
.not_to be_mortgage_over_soft_max
end
end
end
end

16
spec/requests/organisation_relationships_controller_spec.rb

@ -139,8 +139,8 @@ RSpec.describe OrganisationRelationshipsController, type: :request do
let(:params) do
{
"organisation": {
"related_organisation_id": housing_provider.id,
"organisation_relationship": {
"parent_organisation_id": housing_provider.id,
},
}
end
@ -167,8 +167,8 @@ RSpec.describe OrganisationRelationshipsController, type: :request do
let(:params) do
{
"organisation": {
"related_organisation_id": managing_agent.id,
"organisation_relationship": {
"child_organisation_id": managing_agent.id,
},
}
end
@ -368,8 +368,8 @@ RSpec.describe OrganisationRelationshipsController, type: :request do
let(:params) do
{
"organisation": {
"related_organisation_id": housing_provider.id,
"organisation_relationship": {
"parent_organisation_id": housing_provider.id,
},
}
end
@ -396,8 +396,8 @@ RSpec.describe OrganisationRelationshipsController, type: :request do
let(:params) do
{
"organisation": {
"related_organisation_id": managing_agent.id,
"organisation_relationship": {
"child_organisation_id": managing_agent.id,
},
}
end

Loading…
Cancel
Save