Browse Source

Merge branch 'main' into CLDC-1583-extrabor-compound-validation

# Conflicts:
#	app/models/validations/sales/soft_validations.rb
#	db/schema.rb
#	spec/models/form_handler_spec.rb
pull/1201/head
natdeanlewissoftwire 4 years ago
parent
commit
4b67c90133
  1. 149
      Gemfile.lock
  2. 16
      app/models/form/question.rb
  3. 13
      app/models/form/sales/pages/handover_date_check.rb
  4. 14
      app/models/form/sales/questions/age1.rb
  5. 4
      app/models/form/sales/questions/age2.rb
  6. 3
      app/models/form/sales/questions/buyer1_age_known.rb
  7. 4
      app/models/form/sales/questions/buyer1_ethnic_group.rb
  8. 6
      app/models/form/sales/questions/buyer1_working_situation.rb
  9. 8
      app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb
  10. 6
      app/models/form/sales/questions/buyer2_working_situation.rb
  11. 6
      app/models/form/sales/questions/gender_identity2.rb
  12. 23
      app/models/form/sales/questions/handover_date_check.rb
  13. 6
      app/models/form/sales/questions/nationality1.rb
  14. 4
      app/models/form/sales/questions/person_age.rb
  15. 6
      app/models/form/sales/questions/person_gender_identity.rb
  16. 6
      app/models/form/sales/questions/person_relationship_to_buyer_1.rb
  17. 6
      app/models/form/sales/questions/person_working_situation.rb
  18. 4
      app/models/form/sales/questions/postcode.rb
  19. 4
      app/models/form/sales/questions/previous_postcode.rb
  20. 4
      app/models/form/sales/questions/prevloc.rb
  21. 1
      app/models/form/sales/subsections/shared_ownership_scheme.rb
  22. 1
      app/models/sales_log.rb
  23. 19
      app/models/validations/household_validations.rb
  24. 55
      app/models/validations/sales/household_validations.rb
  25. 8
      app/models/validations/sales/sale_information_validations.rb
  26. 6
      app/models/validations/sales/soft_validations.rb
  27. 15
      app/models/validations/shared_validations.rb
  28. 44
      config/forms/2021_2022.json
  29. 44
      config/forms/2022_2023.json
  30. 4
      config/forms/schema/generic.json
  31. 15
      config/locales/en.yml
  32. 7
      db/migrate/20230116151942_add_ho_date_check.rb
  33. 14
      db/schema.rb
  34. 4
      docs/form/builder.md
  35. 4
      docs/form/question.md
  36. 12
      spec/factories/sales_log.rb
  37. 8
      spec/fixtures/forms/2021_2022.json
  38. 33
      spec/models/form/sales/pages/handover_date_check_spec.rb
  39. 14
      spec/models/form/sales/questions/age1_spec.rb
  40. 4
      spec/models/form/sales/questions/age2_spec.rb
  41. 17
      spec/models/form/sales/questions/buyer1_age_known_spec.rb
  42. 9
      spec/models/form/sales/questions/buyer1_ethnic_group_spec.rb
  43. 6
      spec/models/form/sales/questions/buyer1_working_situation_spec.rb
  44. 8
      spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb
  45. 6
      spec/models/form/sales/questions/buyer2_working_situation_spec.rb
  46. 6
      spec/models/form/sales/questions/gender_identity2_spec.rb
  47. 48
      spec/models/form/sales/questions/handover_date_check_spec.rb
  48. 6
      spec/models/form/sales/questions/nationality1_spec.rb
  49. 32
      spec/models/form/sales/questions/person_age_spec.rb
  50. 48
      spec/models/form/sales/questions/person_gender_identity_spec.rb
  51. 48
      spec/models/form/sales/questions/person_relationship_to_buyer1_spec.rb
  52. 48
      spec/models/form/sales/questions/person_working_situation_spec.rb
  53. 4
      spec/models/form/sales/questions/postcode_spec.rb
  54. 4
      spec/models/form/sales/questions/previous_postcode_spec.rb
  55. 4
      spec/models/form/sales/questions/prevloc_spec.rb
  56. 1
      spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb
  57. 4
      spec/models/form_handler_spec.rb
  58. 13
      spec/models/sales_log_spec.rb
  59. 12
      spec/models/validations/household_validations_spec.rb
  60. 65
      spec/models/validations/sales/household_validations_spec.rb
  61. 62
      spec/models/validations/sales/sale_information_validations_spec.rb
  62. 39
      spec/models/validations/sales/soft_validations_spec.rb

149
Gemfile.lock

@ -13,67 +13,67 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (7.0.4)
actionpack (= 7.0.4)
activesupport (= 7.0.4)
actioncable (7.0.4.1)
actionpack (= 7.0.4.1)
activesupport (= 7.0.4.1)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (7.0.4)
actionpack (= 7.0.4)
activejob (= 7.0.4)
activerecord (= 7.0.4)
activestorage (= 7.0.4)
activesupport (= 7.0.4)
actionmailbox (7.0.4.1)
actionpack (= 7.0.4.1)
activejob (= 7.0.4.1)
activerecord (= 7.0.4.1)
activestorage (= 7.0.4.1)
activesupport (= 7.0.4.1)
mail (>= 2.7.1)
net-imap
net-pop
net-smtp
actionmailer (7.0.4)
actionpack (= 7.0.4)
actionview (= 7.0.4)
activejob (= 7.0.4)
activesupport (= 7.0.4)
actionmailer (7.0.4.1)
actionpack (= 7.0.4.1)
actionview (= 7.0.4.1)
activejob (= 7.0.4.1)
activesupport (= 7.0.4.1)
mail (~> 2.5, >= 2.5.4)
net-imap
net-pop
net-smtp
rails-dom-testing (~> 2.0)
actionpack (7.0.4)
actionview (= 7.0.4)
activesupport (= 7.0.4)
actionpack (7.0.4.1)
actionview (= 7.0.4.1)
activesupport (= 7.0.4.1)
rack (~> 2.0, >= 2.2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (7.0.4)
actionpack (= 7.0.4)
activerecord (= 7.0.4)
activestorage (= 7.0.4)
activesupport (= 7.0.4)
actiontext (7.0.4.1)
actionpack (= 7.0.4.1)
activerecord (= 7.0.4.1)
activestorage (= 7.0.4.1)
activesupport (= 7.0.4.1)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.0.4)
activesupport (= 7.0.4)
actionview (7.0.4.1)
activesupport (= 7.0.4.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (7.0.4)
activesupport (= 7.0.4)
activejob (7.0.4.1)
activesupport (= 7.0.4.1)
globalid (>= 0.3.6)
activemodel (7.0.4)
activesupport (= 7.0.4)
activerecord (7.0.4)
activemodel (= 7.0.4)
activesupport (= 7.0.4)
activestorage (7.0.4)
actionpack (= 7.0.4)
activejob (= 7.0.4)
activerecord (= 7.0.4)
activesupport (= 7.0.4)
activemodel (7.0.4.1)
activesupport (= 7.0.4.1)
activerecord (7.0.4.1)
activemodel (= 7.0.4.1)
activesupport (= 7.0.4.1)
activestorage (7.0.4.1)
actionpack (= 7.0.4.1)
activejob (= 7.0.4.1)
activerecord (= 7.0.4.1)
activesupport (= 7.0.4.1)
marcel (~> 1.0)
mini_mime (>= 1.1.0)
activesupport (7.0.4)
activesupport (7.0.4.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@ -136,6 +136,7 @@ GEM
crack (0.4.5)
rexml
crass (1.0.6)
date (3.3.3)
devise_two_factor_authentication (3.0.0)
devise
encryptor
@ -143,7 +144,6 @@ GEM
randexp
rotp (>= 4.0.0)
diff-lcs (1.5.0)
digest (3.1.0)
docile (1.4.0)
dotenv (2.8.1)
dotenv-rails (2.8.1)
@ -157,7 +157,7 @@ GEM
rainbow
rubocop
smart_properties
erubi (1.11.0)
erubi (1.12.0)
excon (0.92.5)
factory_bot (6.2.1)
activesupport (>= 5.0.0)
@ -167,7 +167,7 @@ GEM
faker (2.23.0)
i18n (>= 1.8.11, < 2)
ffi (1.15.5)
globalid (1.0.0)
globalid (1.0.1)
activesupport (>= 5.0)
govuk-components (3.2.1)
actionpack (>= 6.1)
@ -202,34 +202,32 @@ GEM
loofah (2.19.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mail (2.8.0.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.2)
matrix (0.4.2)
method_source (1.0.0)
mini_mime (1.1.2)
minitest (5.16.3)
minitest (5.17.0)
msgpack (1.5.6)
net-imap (0.2.3)
digest
net-imap (0.3.4)
date
net-protocol
strscan
net-pop (0.1.1)
digest
net-pop (0.1.2)
net-protocol
net-protocol (0.2.1)
timeout
net-protocol (0.1.3)
timeout
net-smtp (0.3.1)
digest
net-smtp (0.3.3)
net-protocol
timeout
nio4r (2.5.8)
nokogiri (1.13.10-arm64-darwin)
nokogiri (1.14.0-arm64-darwin)
racc (~> 1.4)
nokogiri (1.13.10-x86_64-darwin)
nokogiri (1.14.0-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.10-x86_64-linux)
nokogiri (1.14.0-x86_64-linux)
racc (~> 1.4)
notifications-ruby-client (5.3.0)
jwt (>= 1.5, < 3)
@ -269,36 +267,36 @@ GEM
public_suffix (5.0.0)
puma (5.6.5)
nio4r (~> 2.0)
racc (1.6.1)
rack (2.2.4)
racc (1.6.2)
rack (2.2.6.2)
rack-attack (6.6.1)
rack (>= 1.0, < 3)
rack-mini-profiler (2.3.4)
rack (>= 1.2.0)
rack-test (2.0.2)
rack (>= 1.3)
rails (7.0.4)
actioncable (= 7.0.4)
actionmailbox (= 7.0.4)
actionmailer (= 7.0.4)
actionpack (= 7.0.4)
actiontext (= 7.0.4)
actionview (= 7.0.4)
activejob (= 7.0.4)
activemodel (= 7.0.4)
activerecord (= 7.0.4)
activestorage (= 7.0.4)
activesupport (= 7.0.4)
rails (7.0.4.1)
actioncable (= 7.0.4.1)
actionmailbox (= 7.0.4.1)
actionmailer (= 7.0.4.1)
actionpack (= 7.0.4.1)
actiontext (= 7.0.4.1)
actionview (= 7.0.4.1)
activejob (= 7.0.4.1)
activemodel (= 7.0.4.1)
activerecord (= 7.0.4.1)
activestorage (= 7.0.4.1)
activesupport (= 7.0.4.1)
bundler (>= 1.15.0)
railties (= 7.0.4)
railties (= 7.0.4.1)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.4.4)
loofah (~> 2.19, >= 2.19.1)
railties (7.0.4)
actionpack (= 7.0.4)
activesupport (= 7.0.4)
railties (7.0.4.1)
actionpack (= 7.0.4.1)
activesupport (= 7.0.4.1)
method_source
rake (>= 12.2)
thor (~> 1.0)
@ -396,10 +394,9 @@ GEM
smart_properties (1.17.0)
stimulus-rails (1.1.0)
railties (>= 6.0.0)
strscan (3.0.4)
thor (1.2.1)
timecop (0.9.5)
timeout (0.3.0)
timeout (0.3.1)
tzinfo (2.0.5)
concurrent-ruby (~> 1.0)
uk_postcode (2.1.8)
@ -425,7 +422,7 @@ GEM
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.0)
zeitwerk (2.6.6)
PLATFORMS
arm64-darwin-21

16
app/models/form/question.rb

@ -53,10 +53,7 @@ class Form::Question
answer = label_from_value(log[id]) if log[id].present?
answer_label = [prefix, format_value(answer), suffix_label(log)].join("") if answer
inferred = inferred_check_answers_value["value"] if inferred_check_answers_value && has_inferred_check_answers_value?(log)
return inferred if inferred.present?
answer_label
inferred_answer_value(log) || answer_label
end
def get_inferred_answers(log)
@ -104,7 +101,7 @@ class Form::Question
def has_inferred_check_answers_value?(log)
return true if selected_answer_option_is_derived?(log)
return inferred_check_answers_value["condition"].values[0] == log[inferred_check_answers_value["condition"].keys[0]] if inferred_check_answers_value.present?
return inferred_check_answers_value&.any? { |inferred_value| inferred_value["condition"].values.first == log[inferred_value["condition"].keys.first] } if inferred_check_answers_value.present?
false
end
@ -271,7 +268,7 @@ private
end
def has_inferred_display_value?(log)
inferred_check_answers_value.present? && log[inferred_check_answers_value["condition"].keys.first] == inferred_check_answers_value["condition"].values.first
inferred_check_answers_value.present? && inferred_check_answers_value.any? { |inferred_value| log[inferred_value["condition"].keys.first] == inferred_value["condition"].values.first }
end
def checkbox_answer_label(log)
@ -309,6 +306,13 @@ private
inferred_answers.filter { |_key, value| value.all? { |condition_key, condition_value| log[condition_key] == condition_value } }
end
def inferred_answer_value(log)
return unless inferred_check_answers_value
inferred_answer = inferred_check_answers_value.find { |inferred_value| inferred_value["condition"].values.first == log[inferred_value["condition"].keys.first] }
inferred_answer["value"] if inferred_answer.present?
end
RADIO_YES_VALUE = {
renewal: [1],
postcode_known: [1],

13
app/models/form/sales/pages/handover_date_check.rb

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

14
app/models/form/sales/questions/age1.rb

@ -6,12 +6,16 @@ class Form::Sales::Questions::Age1 < ::Form::Question
@header = "Age"
@type = "numeric"
@width = 2
@inferred_check_answers_value = {
"condition" => {
"age1_known" => 1,
@inferred_check_answers_value = [
{
"condition" => { "age1_known" => 1 },
"value" => "Not known",
},
"value" => "Not known",
}
{
"condition" => { "age1_known" => 2 },
"value" => "Prefers not to say",
},
]
@check_answers_card_number = 1
end
end

4
app/models/form/sales/questions/age2.rb

@ -6,10 +6,10 @@ class Form::Sales::Questions::Age2 < ::Form::Question
@header = "Age"
@type = "numeric"
@width = 2
@inferred_check_answers_value = {
@inferred_check_answers_value = [{
"condition" => { "age2_known" => 1 },
"value" => "Not known",
}
}]
@check_answers_card_number = 2
end
end

3
app/models/form/sales/questions/buyer1_age_known.rb

@ -18,6 +18,9 @@ class Form::Sales::Questions::Buyer1AgeKnown < ::Form::Question
{
"age1_known" => 1,
},
{
"age1_known" => 2,
},
],
}
@check_answers_card_number = 1

4
app/models/form/sales/questions/buyer1_ethnic_group.rb

@ -7,12 +7,12 @@ class Form::Sales::Questions::Buyer1EthnicGroup < ::Form::Question
@type = "radio"
@answer_options = ANSWER_OPTIONS
@hint_text = "Buyer 1 is the person in the household who does the most paid work. If it’s a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest."
@inferred_check_answers_value = {
@inferred_check_answers_value = [{
"condition" => {
"ethnic_group" => 17,
},
"value" => "Prefers not to say",
}
}]
@check_answers_card_number = 1
end

6
app/models/form/sales/questions/buyer1_working_situation.rb

@ -8,6 +8,12 @@ class Form::Sales::Questions::Buyer1WorkingSituation < ::Form::Question
@answer_options = ANSWER_OPTIONS
@hint_text = "Buyer 1 is the person in the household who does the most paid work. If it's a joint purchase and the buyers do the same amount of paid work, buyer 1 is whoever is the oldest."
@check_answers_card_number = 1
@inferred_check_answers_value = [{
"condition" => {
"ecstat1" => 10,
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

8
app/models/form/sales/questions/buyer2_relationship_to_buyer1.rb

@ -7,10 +7,16 @@ class Form::Sales::Questions::Buyer2RelationshipToBuyer1 < ::Form::Question
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 2
@inferred_check_answers_value = [{
"condition" => {
"relat2" => "R",
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {
"P" => { "value" => "Parent" },
"P" => { "value" => "Partner" },
"C" => { "value" => "Child", "hint" => "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education." },
"X" => { "value" => "Other" },
"R" => { "value" => "Buyer prefers not to say" },

6
app/models/form/sales/questions/buyer2_working_situation.rb

@ -7,6 +7,12 @@ class Form::Sales::Questions::Buyer2WorkingSituation < ::Form::Question
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 2
@inferred_check_answers_value = [{
"condition" => {
"ecstat2" => 10,
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

6
app/models/form/sales/questions/gender_identity2.rb

@ -7,6 +7,12 @@ class Form::Sales::Questions::GenderIdentity2 < ::Form::Question
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = 2
@inferred_check_answers_value = [{
"condition" => {
"sex2" => "R",
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

23
app/models/form/sales/questions/handover_date_check.rb

@ -0,0 +1,23 @@
class Form::Sales::Questions::HandoverDateCheck < ::Form::Question
def initialize(id, hsh, page)
super
@id = "hodate_check"
@check_answer_label = "Practical completion or handover date check"
@header = "Are you sure practical completion or handover date is more than 3 years before exchange date?"
@type = "interruption_screen"
@answer_options = {
"0" => { "value" => "Yes" },
"1" => { "value" => "No" },
}
@hidden_in_check_answers = {
"depends_on" => [
{
"hodate_check" => 0,
},
{
"hodate_check" => 1,
},
],
}
end
end

6
app/models/form/sales/questions/nationality1.rb

@ -18,6 +18,12 @@ class Form::Sales::Questions::Nationality1 < ::Form::Question
],
}
@check_answers_card_number = 1
@inferred_check_answers_value = [{
"condition" => {
"national" => 13,
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

4
app/models/form/sales/questions/person_age.rb

@ -5,10 +5,10 @@ class Form::Sales::Questions::PersonAge < Form::Sales::Questions::Person
@header = "Age"
@type = "numeric"
@width = 3
@inferred_check_answers_value = {
@inferred_check_answers_value = [{
"condition" => { field_for_person("age", "_known") => 1 },
"value" => "Not known",
}
}]
@check_answers_card_number = person_index
end
end

6
app/models/form/sales/questions/person_gender_identity.rb

@ -6,6 +6,12 @@ class Form::Sales::Questions::PersonGenderIdentity < ::Form::Sales::Questions::P
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = person_index
@inferred_check_answers_value = [{
"condition" => {
id => "R",
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

6
app/models/form/sales/questions/person_relationship_to_buyer_1.rb

@ -6,6 +6,12 @@ class Form::Sales::Questions::PersonRelationshipToBuyer1 < ::Form::Sales::Questi
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = person_index
@inferred_check_answers_value = [{
"condition" => {
id => "R",
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

6
app/models/form/sales/questions/person_working_situation.rb

@ -6,6 +6,12 @@ class Form::Sales::Questions::PersonWorkingSituation < ::Form::Sales::Questions:
@type = "radio"
@answer_options = ANSWER_OPTIONS
@check_answers_card_number = person_index
@inferred_check_answers_value = [{
"condition" => {
id => 10,
},
"value" => "Prefers not to say",
}]
end
ANSWER_OPTIONS = {

4
app/models/form/sales/questions/postcode.rb

@ -6,12 +6,12 @@ class Form::Sales::Questions::Postcode < ::Form::Question
@header = "Postcode"
@type = "text"
@width = 5
@inferred_check_answers_value = {
@inferred_check_answers_value = [{
"condition" => {
"pcodenk" => 1,
},
"value" => "Not known",
}
}]
@inferred_answers = {
"la" => {
"is_la_inferred" => true,

4
app/models/form/sales/questions/previous_postcode.rb

@ -6,12 +6,12 @@ class Form::Sales::Questions::PreviousPostcode < ::Form::Question
@header = "Postcode"
@type = "text"
@width = 5
@inferred_check_answers_value = {
@inferred_check_answers_value = [{
"condition" => {
"ppcodenk" => 1,
},
"value" => "Not known",
}
}]
@inferred_answers = {
"prevloc" => {
"is_previous_la_inferred" => true,

4
app/models/form/sales/questions/prevloc.rb

@ -6,12 +6,12 @@ class Form::Sales::Questions::Prevloc < ::Form::Question
@header = "Select a local authority"
@type = "select"
@answer_options = ANSWER_OPTIONS
@inferred_check_answers_value = {
@inferred_check_answers_value = [{
"condition" => {
"previous_la_known" => 0,
},
"value" => "Not known",
}
}]
end
ANSWER_OPTIONS = {

1
app/models/form/sales/subsections/shared_ownership_scheme.rb

@ -14,6 +14,7 @@ class Form::Sales::Subsections::SharedOwnershipScheme < ::Form::Subsection
Form::Sales::Pages::Resale.new(nil, nil, self),
Form::Sales::Pages::ExchangeDate.new(nil, nil, self),
Form::Sales::Pages::HandoverDate.new(nil, nil, self),
Form::Sales::Pages::HandoverDateCheck.new("handover_date_check", nil, self),
Form::Sales::Pages::LaNominations.new(nil, nil, self),
Form::Sales::Pages::BuyerPrevious.new(nil, nil, self),
Form::Sales::Pages::PreviousBedrooms.new(nil, nil, self),

1
app/models/sales_log.rb

@ -2,7 +2,6 @@ class SalesLogValidator < ActiveModel::Validator
include Validations::Sales::HouseholdValidations
include Validations::Sales::FinancialValidations
include Validations::Sales::SaleInformationValidations
include Validations::SharedValidations
include Validations::LocalAuthorityValidations

19
app/models/validations/household_validations.rb

@ -47,7 +47,7 @@ module Validations::HouseholdValidations
validate_person_age_matches_relationship(record, n)
validate_person_age_and_relationship_matches_economic_status(record, n)
end
validate_partner_count(record)
shared_validate_partner_count(record, 8)
end
def validate_person_1_economic(record)
@ -177,16 +177,9 @@ private
return unless age && economic_status && relationship
if age >= 16 && age <= 19 && tenant_is_child?(relationship) && (!tenant_is_fulltime_student?(economic_status) && !tenant_economic_status_refused?(economic_status))
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19", person_num:)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19", person_num:)
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19", person_num:)
end
end
def validate_partner_count(record)
partner_count = (2..8).count { |n| tenant_is_partner?(record["relat#{n}"]) }
if partner_count > 1
record.errors.add :base, I18n.t("validations.household.relat.one_partner")
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.not_student_16_19", person_num:)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.not_student_16_19", person_num:)
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.not_student_16_19", person_num:)
end
end
@ -202,10 +195,6 @@ private
economic_status == 10
end
def tenant_is_partner?(relationship)
relationship == "P"
end
def tenant_is_child?(relationship)
relationship == "C"
end

55
app/models/validations/sales/household_validations.rb

@ -1,4 +1,6 @@
module Validations::Sales::HouseholdValidations
include Validations::SharedValidations
def validate_number_of_other_people_living_in_the_property(record)
return if record.hholdcount.blank?
@ -6,4 +8,57 @@ module Validations::Sales::HouseholdValidations
record.errors.add :hholdcount, I18n.t("validations.numeric.valid", field: "Number of other people living in the property", min: 0, max: 4)
end
end
def validate_household_number_of_other_members(record)
(2..6).each do |n|
validate_person_age_matches_relationship(record, n)
validate_person_age_and_relationship_matches_economic_status(record, n)
end
shared_validate_partner_count(record, 6)
end
private
def validate_person_age_matches_relationship(record, person_num)
age = record.public_send("age#{person_num}")
relationship = record.public_send("relat#{person_num}")
return unless age && relationship
if age < 16 && person_is_partner?(relationship)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.partner_under_16")
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.partner_under_16")
elsif age >= 20 && person_is_child?(relationship)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.child_over_20")
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.child_over_20")
end
end
def validate_person_age_and_relationship_matches_economic_status(record, person_num)
age = record.public_send("age#{person_num}")
economic_status = record.public_send("ecstat#{person_num}")
relationship = record.public_send("relat#{person_num}")
return unless age && economic_status && relationship
if age >= 16 && age <= 19 && person_is_fulltime_student?(economic_status) && !person_is_child?(relationship)
record.errors.add "age#{person_num}", I18n.t("validations.household.age.student_16_19")
record.errors.add "ecstat#{person_num}", I18n.t("validations.household.ecstat.student_16_19")
record.errors.add "relat#{person_num}", I18n.t("validations.household.relat.student_16_19")
end
end
def person_is_partner?(relationship)
relationship == "P"
end
def person_is_fulltime_student?(economic_status)
economic_status == 7
end
def person_economic_status_refused?(economic_status)
economic_status == 10
end
def person_is_child?(relationship)
relationship == "C"
end
end

8
app/models/validations/sales/sale_information_validations.rb

@ -6,4 +6,12 @@ module Validations::Sales::SaleInformationValidations
record.errors.add :deposit, "Cash deposit must be £0 - £999,999"
end
end
def validate_pratical_completion_date_before_saledate(record)
return if record.saledate.blank? || record.hodate.blank?
unless record.saledate > record.hodate
record.errors.add :hodate, "Practical completion or handover date must be before exchange date"
end
end
end

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

@ -42,4 +42,10 @@ module Validations::Sales::SoftValidations
extrabor != 1 && mortgage + deposit > value - value * discount / 100
end
def hodate_3_years_or_more_saledate?
return unless hodate && saledate
((saledate.to_date - hodate.to_date).to_i / 365) >= 3
end
end

15
app/models/validations/shared_validations.rb

@ -89,4 +89,19 @@ module Validations::SharedValidations
record.errors.add(question_id, I18n.t("validations.invalid_option", question: question.check_answer_label&.downcase))
end
end
def shared_validate_partner_count(record, max_people)
partner_numbers = (2..max_people).select { |n| person_is_partner?(record["relat#{n}"]) }
if partner_numbers.count > 1
partner_numbers.each do |n|
record.errors.add "relat#{n}", I18n.t("validations.household.relat.one_partner")
end
end
end
private
def person_is_partner?(relationship)
relationship == "P"
end
end

44
config/forms/2021_2022.json

@ -59,12 +59,12 @@
"is_la_inferred": true
}
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"postcode_known": 0
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -1298,12 +1298,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age1_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -2077,12 +2077,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age2_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -2612,12 +2612,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age3_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -3144,12 +3144,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age4_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -3673,12 +3673,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age5_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -4199,12 +4199,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age6_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -4722,12 +4722,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age7_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -5242,12 +5242,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age8_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -6517,12 +6517,12 @@
"is_previous_la_inferred": true
}
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"ppcodenk": 0
},
"value": "Not known"
}
}]
}
}
},
@ -6950,12 +6950,12 @@
"W92000004": "Wales",
"9300000XX": "Outside UK"
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"previous_la_known": 0
},
"value": "Not known"
}
}]
}
},
"depends_on": [

44
config/forms/2022_2023.json

@ -59,12 +59,12 @@
"is_la_inferred": true
}
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"postcode_known": 0
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -1333,12 +1333,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age1_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -2076,12 +2076,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age2_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -2611,12 +2611,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age3_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -3143,12 +3143,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age4_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -3672,12 +3672,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age5_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -4198,12 +4198,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age6_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -4721,12 +4721,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age7_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -5241,12 +5241,12 @@
"max": 120,
"step": 1,
"width": 2,
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"age8_known": 1
},
"value": "Not known"
}
}]
}
},
"depends_on": [
@ -6482,12 +6482,12 @@
"is_previous_la_inferred": true
}
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"ppcodenk": 0
},
"value": "Not known"
}
}]
}
}
},
@ -6915,12 +6915,12 @@
"W92000004": "Wales",
"9300000XX": "Outside UK"
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"previous_la_known": 0
},
"value": "Not known"
}
}]
}
},
"depends_on": [

4
config/forms/schema/generic.json

@ -115,7 +115,7 @@
"description": "fields that get inferred based on the value of the current field",
"type": "object"
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"description": "value that gets displayed in the check answers for this field if the given condition is met",
"type": "object",
"properties": {
@ -128,7 +128,7 @@
"type": "object"
}
}
}
}]
},
"minProperties": 1
}

15
config/locales/en.yml

@ -295,20 +295,27 @@ en:
child_under_16_relat: "Answer cannot be under 16 as person %{person_num} is not a child of the lead tenant"
child_under_16: "Answer cannot be under 16 as person’s %{person_num} working situation is not ‘child under 16’"
child_over_16: "Answer cannot be over 16 as person’s %{person_num} working situation is ‘child under 16‘"
student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student"
child_over_20: "Answer cannot be 20 or over as the relationship is ‘child’"
not_student_16_19: "Answer cannot be between 16 and 19 as person %{person_num} is a child of the lead tenant but is not a full-time student"
student_16_19: "Person cannot be aged 16-19 if they are a student but don't have relationship ‘child’"
partner_under_16: "Cannot be under 16 if the relationship is partner"
lead:
over_20: "The lead tenant must be under 20 as you told us their housing situation immediately before this letting was a children’s home or foster care"
ecstat:
retired_over_70: "Person %{person_num} must be retired if over 70"
child_under_16: "Person’s %{person_num} working situation must be ’child under 16‘ as you told us they’re under 16"
child_over_16: "Answer cannot be ‘child under 16’ as you told us the person %{person_num} is older than 16"
student_16_19: "Person’s %{person_num} working situation must be full-time student or prefers not to say as you told us they’re between 16 and 19."
not_student_16_19: "Person’s %{person_num} working situation must be full-time student or prefers not to say as you told us they’re between 16 and 19."
student_16_19: "Person cannot be a student if they are aged 16-19 and but don't have relationship ‘child’"
retired_male: "Answer cannot be ‘retired’ as the male tenant is under 65"
retired_female: "Answer cannot be ‘retired’ as the female tenant is under 60"
relat:
child_under_16: "Person’s %{person_num}’s relationship to tenant 1 must be ‘child’ as you told us they’re under 16"
partner_under_16: "Answer cannot be ‘partner’ if the person's age is under 16"
child_under_16: "Person’s relationship to tenant 1 must be ‘child’ as you told us they’re under 16"
child_over_20: "Answer cannot be ‘child’ if the person's age is 20 or over"
one_partner: "Number of partners cannot be greater than 1"
student_16_19: "Answer cannot be ‘child’ as you told us the person %{person_num} is between 16 and 19 and is not a full-time student"
not_student_16_19: "Answer cannot be ‘child’ as you told us the person %{person_num} is between 16 and 19 and is not a full-time student"
student_16_19: "Answer must be ‘child’ if the person is aged 16-19 and a student"
housingneeds_a:
one_or_two_choices: "You can only select one option or ‘other disabled access needs’ plus ‘wheelchair-accessible housing’, ‘wheelchair access to essential rooms’ or ‘level access housing’"
prevten:

7
db/migrate/20230116151942_add_ho_date_check.rb

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

14
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: 2023_01_18_170602) do
ActiveRecord::Schema[7.0].define(version: 2023_01_16_151942) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -488,17 +488,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_18_170602) do
t.integer "mortgagelender"
t.string "mortgagelenderother"
t.integer "mortlen"
t.string "pcode1"
t.string "pcode2"
t.integer "pcodenk"
t.string "postcode_full"
t.boolean "is_la_inferred"
t.integer "extrabor"
t.integer "hhmemb"
t.integer "totadult"
t.integer "totchild"
t.integer "hhtype"
t.integer "extrabor_value_check"
t.string "pcode1"
t.string "pcode2"
t.integer "pcodenk"
t.string "postcode_full"
t.boolean "is_la_inferred"
t.integer "hodate_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"

4
docs/form/builder.md

@ -82,10 +82,10 @@ The JSON should follow the structure:
"[snake_case_question_to_enable_2_name_string]": ["condition-that-enables"]
},
"inferred_answers": { "field_that_gets_inferred_from_current_field": { "is_that_field_inferred": true } },
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": { "field_name_for_inferred_check_answers_condition": "field_value_for_inferred_check_answers_condition" },
"value": "Inferred value that gets displayed if condition is met"
}
}]
}
},
"depends_on": [{ "question_key": "answer_value_required_for_this_page_to_be_shown" }]

4
docs/form/question.md

@ -74,12 +74,12 @@ The answer the data inputter provides to some questions allows us to infer the v
"is_la_inferred": true
}
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"postcode_known": 0
},
"value": "Not known"
}
}]
}
```

12
spec/factories/sales_log.rb

@ -41,10 +41,10 @@ FactoryBot.define do
wheel { 1 }
details_known_1 { 1 }
age3_known { 0 }
age3 { 40 }
age3 { 14 }
details_known_2 { 1 }
age4_known { 0 }
age4 { 40 }
age4 { 18 }
details_known_3 { 1 }
age5_known { 0 }
age5 { 40 }
@ -85,10 +85,10 @@ FactoryBot.define do
ppcodenk { 1 }
prevten { 1 }
previous_la_known { 0 }
relat3 { "P" }
relat4 { "P" }
relat5 { "P" }
relat6 { "P" }
relat3 { "C" }
relat4 { "X" }
relat5 { "R" }
relat6 { "R" }
hb { 4 }
mortgageused { 1 }
wchair { 1 }

8
spec/fixtures/forms/2021_2022.json vendored

@ -342,12 +342,12 @@
1
]
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"armedforces": 3
},
"value": "Prefers not to say"
}
}]
},
"leftreg": {
"header": "Are they still serving?",
@ -526,12 +526,12 @@
"is_la_inferred": true
}
},
"inferred_check_answers_value": {
"inferred_check_answers_value": [{
"condition": {
"postcode_known": 0
},
"value": "Not known"
}
}]
}
}
},

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

@ -0,0 +1,33 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::HandoverDateCheck, type: :model do
subject(:page) { described_class.new(page_id, page_definition, subsection) }
let(:page_id) { "" }
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[hodate_check])
end
it "has the correct id" do
expect(page.id).to eq("")
end
it "has the correct header" do
expect(page.header).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([
{
"hodate_3_years_or_more_saledate?" => true,
},
])
end
end

14
spec/models/form/sales/questions/age1_spec.rb

@ -40,10 +40,16 @@ RSpec.describe Form::Sales::Questions::Age1, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
"condition" => { "age1_known" => 1 },
"value" => "Not known",
})
expect(question.inferred_check_answers_value).to eq([
{
"condition" => { "age1_known" => 1 },
"value" => "Not known",
},
{
"condition" => { "age1_known" => 2 },
"value" => "Prefers not to say",
},
])
end
it "has the correct check_answers_card_number" do

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

@ -40,12 +40,12 @@ RSpec.describe Form::Sales::Questions::Age2, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => {
"age2_known" => 1,
},
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do

17
spec/models/form/sales/questions/buyer1_age_known_spec.rb

@ -51,12 +51,17 @@ RSpec.describe Form::Sales::Questions::Buyer1AgeKnown, type: :model do
it "has correct hidden_in_check_answers for" do
expect(question.hidden_in_check_answers).to eq({
"depends_on" => [{
"age1_known" => 0,
},
{
"age1_known" => 1,
}],
"depends_on" => [
{
"age1_known" => 0,
},
{
"age1_known" => 1,
},
{
"age1_known" => 2,
},
],
})
end

9
spec/models/form/sales/questions/buyer1_ethnic_group_spec.rb

@ -50,4 +50,13 @@ RSpec.describe Form::Sales::Questions::Buyer1EthnicGroup, type: :model do
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([{
"condition" => {
"ethnic_group" => 17,
},
"value" => "Prefers not to say",
}])
end
end

6
spec/models/form/sales/questions/buyer1_working_situation_spec.rb

@ -49,4 +49,10 @@ RSpec.describe Form::Sales::Questions::Buyer1WorkingSituation, type: :model do
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat1" => 10 }, "value" => "Prefers not to say" },
])
end
end

8
spec/models/form/sales/questions/buyer2_relationship_to_buyer1_spec.rb

@ -37,7 +37,7 @@ RSpec.describe Form::Sales::Questions::Buyer2RelationshipToBuyer1, type: :model
it "has the correct answer_options" do
expect(question.answer_options).to eq({
"P" => { "value" => "Parent" },
"P" => { "value" => "Partner" },
"C" => { "value" => "Child", "hint" => "Must be eligible for child benefit, aged under 16 or under 20 if still in full-time education." },
"X" => { "value" => "Other" },
"R" => { "value" => "Buyer prefers not to say" },
@ -47,4 +47,10 @@ RSpec.describe Form::Sales::Questions::Buyer2RelationshipToBuyer1, type: :model
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat2" => "R" }, "value" => "Prefers not to say" },
])
end
end

6
spec/models/form/sales/questions/buyer2_working_situation_spec.rb

@ -54,4 +54,10 @@ RSpec.describe Form::Sales::Questions::Buyer2WorkingSituation, type: :model do
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat2" => 10 }, "value" => "Prefers not to say" },
])
end
end

6
spec/models/form/sales/questions/gender_identity2_spec.rb

@ -43,4 +43,10 @@ RSpec.describe Form::Sales::Questions::GenderIdentity2, type: :model do
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex2" => "R" }, "value" => "Prefers not to say" },
])
end
end

48
spec/models/form/sales/questions/handover_date_check_spec.rb

@ -0,0 +1,48 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::HandoverDateCheck, 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("hodate_check")
end
it "has the correct header" do
expect(question.header).to eq("Are you sure practical completion or handover date is more than 3 years before exchange date?")
end
it "has the correct check_answer_label" do
expect(question.check_answer_label).to eq("Practical completion or handover date check")
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 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" => [{ "hodate_check" => 0 }, { "hodate_check" => 1 }] })
end
end

6
spec/models/form/sales/questions/nationality1_spec.rb

@ -64,4 +64,10 @@ RSpec.describe Form::Sales::Questions::Nationality1, type: :model do
it "has the correct check_answers_card_number" do
expect(question.check_answers_card_number).to eq(1)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "national" => 13 }, "value" => "Prefers not to say" },
])
end
end

32
spec/models/form/sales/questions/person_age_spec.rb

@ -54,10 +54,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age2_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -86,10 +86,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age3_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -118,10 +118,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age4_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -150,10 +150,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age5_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -184,10 +184,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age3_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -216,10 +216,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age4_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -248,10 +248,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age5_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do
@ -280,10 +280,10 @@ RSpec.describe Form::Sales::Questions::PersonAge, type: :model do
end
it "has the correct inferred check answers value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => { "age6_known" => 1 },
"value" => "Not known",
})
}])
end
it "has the correct check_answers_card_number" do

48
spec/models/form/sales/questions/person_gender_identity_spec.rb

@ -61,6 +61,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex2" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -86,6 +92,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex3" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
@ -113,6 +125,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex3" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -138,6 +156,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex4" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
@ -165,6 +189,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex4" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -190,6 +220,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex5" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
@ -217,6 +253,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex5" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -242,6 +284,12 @@ RSpec.describe Form::Sales::Questions::PersonGenderIdentity, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(6)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "sex6" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
end

48
spec/models/form/sales/questions/person_relationship_to_buyer1_spec.rb

@ -61,6 +61,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat2" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -86,6 +92,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat3" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
@ -113,6 +125,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat3" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -138,6 +156,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat4" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
@ -165,6 +189,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat4" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -190,6 +220,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat5" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
@ -217,6 +253,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat5" => "R" }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -242,6 +284,12 @@ RSpec.describe Form::Sales::Questions::PersonRelationshipToBuyer1, type: :model
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(6)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "relat6" => "R" }, "value" => "Prefers not to say" },
])
end
end
end
end

48
spec/models/form/sales/questions/person_working_situation_spec.rb

@ -68,6 +68,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(2)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat2" => 10 }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -93,6 +99,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat3" => 10 }, "value" => "Prefers not to say" },
])
end
end
end
@ -120,6 +132,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(3)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat3" => 10 }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -145,6 +163,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat4" => 10 }, "value" => "Prefers not to say" },
])
end
end
end
@ -172,6 +196,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(4)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat4" => 10 }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -197,6 +227,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat5" => 10 }, "value" => "Prefers not to say" },
])
end
end
end
@ -224,6 +260,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(5)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat5" => 10 }, "value" => "Prefers not to say" },
])
end
end
context "and joint purchase" do
@ -249,6 +291,12 @@ RSpec.describe Form::Sales::Questions::PersonWorkingSituation, type: :model do
it "has expected check answers card number" do
expect(question.check_answers_card_number).to eq(6)
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq([
{ "condition" => { "ecstat6" => 10 }, "value" => "Prefers not to say" },
])
end
end
end
end

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

@ -48,11 +48,11 @@ RSpec.describe Form::Sales::Questions::Postcode, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => {
"pcodenk" => 1,
},
"value" => "Not known",
})
}])
end
end

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

@ -48,11 +48,11 @@ RSpec.describe Form::Sales::Questions::PreviousPostcode, type: :model do
end
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq({
expect(question.inferred_check_answers_value).to eq([{
"condition" => {
"ppcodenk" => 1,
},
"value" => "Not known",
})
}])
end
end

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

@ -422,12 +422,12 @@ RSpec.describe Form::Sales::Questions::Prevloc, type: :model do
it "has the correct inferred_check_answers_value" do
expect(question.inferred_check_answers_value).to eq(
{
[{
"condition" => {
"previous_la_known" => 0,
},
"value" => "Not known",
},
}],
)
end
end

1
spec/models/form/sales/subsections/shared_ownership_scheme_spec.rb

@ -20,6 +20,7 @@ RSpec.describe Form::Sales::Subsections::SharedOwnershipScheme, type: :model do
resale
exchange_contracts
handover_date
handover_date_check
la_nominations
buyer_previous
previous_bedrooms

4
spec/models/form_handler_spec.rb

@ -52,14 +52,14 @@ RSpec.describe FormHandler do
it "is able to load a current sales form" do
form = form_handler.get_form("current_sales")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(151)
expect(form.pages.count).to eq(152)
expect(form.name).to eq("2022_2023_sales")
end
it "is able to load a previous sales form" do
form = form_handler.get_form("previous_sales")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(151)
expect(form.pages.count).to eq(152)
expect(form.name).to eq("2021_2022_sales")
end
end

13
spec/models/sales_log_spec.rb

@ -30,6 +30,19 @@ RSpec.describe SalesLog, type: :model do
end
end
describe "#update" do
let(:sales_log) { FactoryBot.create(:sales_log, created_by: created_by_user) }
let(:validator) { sales_log._validators[nil].first }
after do
sales_log.update(age1: 25)
end
it "validates other household member details" do
expect(validator).to receive(:validate_household_number_of_other_members)
end
end
describe "#optional_fields" do
let(:sales_log) { build(:sales_log) }

12
spec/models/validations/household_validations_spec.rb

@ -332,8 +332,12 @@ RSpec.describe Validations::HouseholdValidations do
record.relat2 = "P"
record.relat3 = "P"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["base"])
expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.one_partner"))
expect(record.errors["relat3"])
.to include(match I18n.t("validations.household.relat.one_partner"))
expect(record.errors["relat4"])
.not_to include(match I18n.t("validations.household.relat.one_partner"))
end
it "expects that a tenant can have a partner" do
@ -398,11 +402,11 @@ RSpec.describe Validations::HouseholdValidations do
record.ecstat2 = 1
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.student_16_19", person_num: 2))
.to include(match I18n.t("validations.household.ecstat.not_student_16_19", person_num: 2))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.student_16_19", person_num: 2))
.to include(match I18n.t("validations.household.age.not_student_16_19", person_num: 2))
expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.student_16_19", person_num: 2))
.to include(match I18n.t("validations.household.relat.not_student_16_19", person_num: 2))
end
it "expects that person can be a full time student" do

65
spec/models/validations/sales/household_validations_spec.rb

@ -46,4 +46,69 @@ RSpec.describe Validations::Sales::HouseholdValidations do
end
end
end
describe "household member validations" do
let(:record) { build(:sales_log) }
it "validates that only 1 partner exists" do
record.relat2 = "P"
record.relat3 = "P"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.one_partner"))
expect(record.errors["relat3"])
.to include(match I18n.t("validations.household.relat.one_partner"))
expect(record.errors["relat4"])
.not_to include(match I18n.t("validations.household.relat.one_partner"))
end
it "expects that a tenant can have a partner" do
record.relat3 = "P"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["base"]).to be_empty
end
context "when the household contains a person under 16" do
it "expects that person is a child of the tenant" do
record.age2 = 14
record.relat2 = "C"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["relat2"]).to be_empty
expect(record.errors["age2"]).to be_empty
end
it "validates that a person under 16 must not be a partner of the buyer" do
record.age2 = 14
record.relat2 = "P"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.partner_under_16"))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.partner_under_16"))
end
end
it "validates that a person over 20 must not be a child of the buyer" do
record.age2 = 21
record.relat2 = "C"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.child_over_20"))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.child_over_20"))
end
it "validates that a person aged 16-19 who is a student must be a child of the buyer" do
record.age2 = 18
record.ecstat2 = "7"
record.relat2 = "P"
household_validator.validate_household_number_of_other_members(record)
expect(record.errors["relat2"])
.to include(match I18n.t("validations.household.relat.student_16_19"))
expect(record.errors["age2"])
.to include(match I18n.t("validations.household.age.student_16_19"))
expect(record.errors["ecstat2"])
.to include(match I18n.t("validations.household.ecstat.student_16_19"))
end
end
end

62
spec/models/validations/sales/sale_information_validations_spec.rb

@ -46,4 +46,66 @@ RSpec.describe Validations::Sales::SaleInformationValidations do
end
end
end
describe "#validate_pratical_completion_date_before_saledate" do
context "when hodate blank" do
let(:record) { build(:sales_log, hodate: nil) }
it "does not add an error" do
sale_information_validator.validate_pratical_completion_date_before_saledate(record)
expect(record.errors).not_to be_present
end
end
context "when saledate blank" do
let(:record) { build(:sales_log, saledate: nil) }
it "does not add an error" do
sale_information_validator.validate_pratical_completion_date_before_saledate(record)
expect(record.errors).not_to be_present
end
end
context "when saledate and hodate blank" do
let(:record) { build(:sales_log, hodate: nil, saledate: nil) }
it "does not add an error" do
sale_information_validator.validate_pratical_completion_date_before_saledate(record)
expect(record.errors).not_to be_present
end
end
context "when hodate before saledate" do
let(:record) { build(:sales_log, hodate: 2.months.ago, saledate: 1.month.ago) }
it "does not add the error" do
sale_information_validator.validate_pratical_completion_date_before_saledate(record)
expect(record.errors).not_to be_present
end
end
context "when hodate after saledate" do
let(:record) { build(:sales_log, hodate: 1.month.ago, saledate: 2.months.ago) }
it "adds error" do
sale_information_validator.validate_pratical_completion_date_before_saledate(record)
expect(record.errors[:hodate]).to be_present
end
end
context "when hodate == saledate" do
let(:record) { build(:sales_log, hodate: Time.zone.parse("2023-07-01"), saledate: Time.zone.parse("2023-07-01")) }
it "does not add an error" do
sale_information_validator.validate_pratical_completion_date_before_saledate(record)
expect(record.errors[:hodate]).to be_present
end
end
end
end

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

@ -1,7 +1,7 @@
require "rails_helper"
RSpec.describe Validations::Sales::SoftValidations do
let(:record) { FactoryBot.create(:sales_log) }
let(:record) { create(:sales_log) }
describe "income1 min validations" do
context "when validating soft min" do
@ -322,4 +322,41 @@ RSpec.describe Validations::Sales::SoftValidations do
end
end
end
describe "hodate_more_than_3_years_before_saledate" do
it "when hodate not set" do
record.saledate = Time.zone.now
record.hodate = nil
expect(record).not_to be_hodate_3_years_or_more_saledate
end
it "when saledate not set" do
record.saledate = nil
record.hodate = Time.zone.now
expect(record).not_to be_hodate_3_years_or_more_saledate
end
it "when saledate and hodate not set" do
record.saledate = nil
record.hodate = nil
expect(record).not_to be_hodate_3_years_or_more_saledate
end
it "when 3 years or more before saledate" do
record.saledate = Time.zone.now
record.hodate = record.saledate - 4.years
expect(record).to be_hodate_3_years_or_more_saledate
end
it "when less than 3 years before saledate" do
record.saledate = Time.zone.now
record.hodate = 2.months.ago
expect(record).not_to be_hodate_3_years_or_more_saledate
end
end
end

Loading…
Cancel
Save