Browse Source

Revert "CLDC-3787 Autocomplete address search (#2924)" (#2965)

This reverts commit 29a469b668.

Co-authored-by: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
pull/2956/head
Manny Dinssa 1 week ago committed by GitHub
parent
commit
f320687294
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 70
      app/controllers/address_search_controller.rb
  2. 8
      app/controllers/test_data_controller.rb
  3. 73
      app/frontend/controllers/address_search_controller.js
  4. 3
      app/frontend/controllers/index.js
  5. 15
      app/models/derived_variables/lettings_log_variables.rb
  6. 49
      app/models/derived_variables/sales_log_variables.rb
  7. 9
      app/models/form/lettings/pages/address_fallback.rb
  8. 17
      app/models/form/lettings/pages/address_search.rb
  9. 44
      app/models/form/lettings/questions/address_search.rb
  10. 1
      app/models/form/lettings/questions/postcode_for_full_address.rb
  11. 6
      app/models/form/lettings/subsections/property_information.rb
  12. 11
      app/models/form/sales/pages/address_fallback.rb
  13. 23
      app/models/form/sales/pages/address_search.rb
  14. 1
      app/models/form/sales/pages/no_address_found.rb
  15. 44
      app/models/form/sales/questions/address_search.rb
  16. 1
      app/models/form/sales/questions/postcode_for_full_address.rb
  17. 6
      app/models/form/sales/subsections/property_information.rb
  18. 18
      app/models/log.rb
  19. 7
      app/services/address_client.rb
  20. 1
      app/services/bulk_upload/lettings/year2024/row_parser.rb
  21. 1
      app/services/bulk_upload/lettings/year2025/row_parser.rb
  22. 1
      app/services/bulk_upload/sales/year2024/row_parser.rb
  23. 1
      app/services/bulk_upload/sales/year2025/row_parser.rb
  24. 22
      app/services/csv/lettings_log_csv_service.rb
  25. 14
      app/services/csv/sales_log_csv_service.rb
  26. 8
      app/services/uprn_data_presenter.rb
  27. 24
      app/views/form/_address_search_question.html.erb
  28. 5
      app/views/form/_select_question.html.erb
  29. 3
      app/views/form/guidance/_address_fallback.html.erb
  30. 7
      app/views/form/guidance/_address_search.html.erb
  31. 7
      config/locales/forms/2024/lettings/guidance.en.yml
  32. 7
      config/locales/forms/2024/lettings/property_information.en.yml
  33. 7
      config/locales/forms/2024/sales/guidance.en.yml
  34. 7
      config/locales/forms/2024/sales/property_information.en.yml
  35. 7
      config/locales/forms/2025/lettings/guidance.en.yml
  36. 45
      config/locales/forms/2025/lettings/property_information.en.yml
  37. 7
      config/locales/forms/2025/sales/guidance.en.yml
  38. 45
      config/locales/forms/2025/sales/property_information.en.yml
  39. 14
      config/locales/validations/sales/property_information.en.yml
  40. 4
      config/routes.rb
  41. 6
      db/migrate/20250219122817_add_manual_address_entry_selected_to_logs.rb
  42. 4
      db/schema.rb
  43. 9
      spec/factories/lettings_log.rb
  44. 10
      spec/factories/sales_log.rb
  45. 45
      spec/features/form/address_search_spec.rb
  46. 60
      spec/features/form/form_navigation_spec.rb
  47. 375
      spec/features/lettings_log_spec.rb
  48. 375
      spec/features/sales_log_spec.rb
  49. 2
      spec/fixtures/files/sales_logs_csv_export_codes_24.csv
  50. 2
      spec/fixtures/files/sales_logs_csv_export_labels_24.csv
  51. 2
      spec/fixtures/files/sales_logs_csv_export_non_support_labels_24.csv
  52. 4
      spec/models/bulk_upload_spec.rb
  53. 9
      spec/models/form/lettings/pages/address_fallback_spec.rb
  54. 42
      spec/models/form/lettings/pages/address_search_spec.rb
  55. 68
      spec/models/form/lettings/questions/address_search_spec.rb
  56. 8
      spec/models/form/lettings/questions/uprn_selection_spec.rb
  57. 4
      spec/models/form/lettings/questions/uprn_spec.rb
  58. 12
      spec/models/form/lettings/subsections/property_information_spec.rb
  59. 9
      spec/models/form/sales/pages/address_fallback_spec.rb
  60. 42
      spec/models/form/sales/pages/address_search_spec.rb
  61. 4
      spec/models/form/sales/pages/uprn_confirmation_spec.rb
  62. 68
      spec/models/form/sales/questions/address_search_spec.rb
  63. 8
      spec/models/form/sales/questions/uprn_selection_spec.rb
  64. 12
      spec/models/form/sales/subsections/property_information_spec.rb
  65. 7
      spec/models/sales_log_spec.rb
  66. 4
      spec/models/validations/sales/property_validations_spec.rb
  67. 2
      spec/request_helper.rb
  68. 148
      spec/requests/address_search_controller_spec.rb
  69. 10
      spec/requests/duplicate_logs_controller_spec.rb
  70. 8
      spec/services/csv/sales_log_csv_service_spec.rb
  71. 2
      spec/services/exports/lettings_log_export_service_spec.rb
  72. 5
      spec/shared/shared_examples_for_derived_fields.rb
  73. 2
      spec/shared/shared_log_examples.rb

70
app/controllers/address_search_controller.rb

@ -1,70 +0,0 @@
class AddressSearchController < ApplicationController
before_action :authenticate_user!
before_action :set_log, only: %i[manual_input search_input]
def index
query = params[:query]
if query.match?(/\A\d+\z/) && query.length > 5
# Query is all numbers and greater than 5 digits, assume it's a UPRN
service = UprnClient.new(query)
service.call
if service.error.present?
render json: { error: service.error }, status: :not_found
else
presenter = UprnDataPresenter.new(service.result)
render json: [{ text: presenter.address, value: presenter.uprn }]
end
elsif query.match?(/[a-zA-Z]/)
# Query contains letters, assume it's an address
service = AddressClient.new(query, { minmatch: 0.2 })
service.call
if service.error.present?
render json: { error: service.error }, status: :not_found
else
results = service.result.map do |result|
presenter = AddressDataPresenter.new(result)
{ text: presenter.address, value: presenter.uprn }
end
render json: results
end
else
# Query is ambiguous, use both APIs and merge results
address_service = AddressClient.new(query, { minmatch: 0.2 })
uprn_service = UprnClient.new(query)
address_service.call
uprn_service.call
results = ([uprn_service.result] || []) + (address_service.result || [])
if address_service.error.present? && uprn_service.error.present?
render json: { error: "Address and UPRN are not recognised." }, status: :not_found
else
formatted_results = results.map do |result|
presenter = AddressDataPresenter.new(result)
{ text: presenter.address, value: presenter.uprn }
end
render json: formatted_results
end
end
end
def manual_input
@log.update!(manual_address_entry_selected: true)
redirect_to polymorphic_url([@log, :address])
end
def search_input
@log.update!(manual_address_entry_selected: false)
redirect_to polymorphic_url([@log, :address_search])
end
private
def set_log
@log = current_user.send("#{params[:log_type]}s").find(params[:log_id])
end
end

8
app/controllers/test_data_controller.rb

@ -4,14 +4,14 @@ class TestDataController < ApplicationController
def create_test_lettings_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:lettings_log, :completed, assigned_to: current_user, ppostcode_full: "SW1A 1AA", manual_address_entry_selected: false)
log = FactoryBot.create(:lettings_log, :completed, assigned_to: current_user, ppostcode_full: "SW1A 1AA")
redirect_to lettings_log_path(log)
end
def create_setup_test_lettings_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:lettings_log, :setup_completed, assigned_to: current_user, manual_address_entry_selected: false)
log = FactoryBot.create(:lettings_log, :setup_completed, assigned_to: current_user)
redirect_to lettings_log_path(log)
end
@ -40,14 +40,14 @@ class TestDataController < ApplicationController
def create_test_sales_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:sales_log, :completed, assigned_to: current_user, manual_address_entry_selected: false)
log = FactoryBot.create(:sales_log, :completed, assigned_to: current_user)
redirect_to sales_log_path(log)
end
def create_setup_test_sales_log
return render_not_found unless FeatureToggle.create_test_logs_enabled?
log = FactoryBot.create(:sales_log, :shared_ownership_setup_complete, assigned_to: current_user, manual_address_entry_selected: false)
log = FactoryBot.create(:sales_log, :shared_ownership_setup_complete, assigned_to: current_user)
redirect_to sales_log_path(log)
end

73
app/frontend/controllers/address_search_controller.js

@ -1,73 +0,0 @@
import { Controller } from '@hotwired/stimulus'
import accessibleAutocomplete from 'accessible-autocomplete'
import 'accessible-autocomplete/dist/accessible-autocomplete.min.css'
const options = []
const fetchOptions = async (query, searchUrl) => {
if (query.length < 2) {
throw new Error('Query must be at least 2 characters long.')
}
try {
const response = await fetch(`${searchUrl}?query=${encodeURIComponent(query.trim())}`)
return await response.json()
} catch (error) {
return error
}
}
const fetchAndPopulateSearchResults = async (query, populateResults, searchUrl, populateOptions, selectEl) => {
if (/\S/.test(query)) {
try {
const results = await fetchOptions(query, searchUrl)
if (results.length === 0) {
populateOptions([], selectEl)
populateResults([])
} else {
populateOptions(results, selectEl)
populateResults(Object.values(results).map((o) => `${o.text} (${o.value})`))
}
} catch (error) {
populateOptions([], selectEl)
populateResults([])
}
}
}
const populateOptions = (results, selectEl) => {
selectEl.innerHTML = ''
results.forEach((result) => {
const option = document.createElement('option')
option.value = result.value
option.innerHTML = `${result.text} (${result.value})`
selectEl.appendChild(option)
options.push(option)
})
}
export default class extends Controller {
connect () {
const searchUrl = JSON.parse(this.element.dataset.info).search_url
const selectEl = this.element
accessibleAutocomplete.enhanceSelectElement({
defaultValue: '',
selectElement: selectEl,
minLength: 2,
source: (query, populateResults) => {
fetchAndPopulateSearchResults(query, populateResults, searchUrl, populateOptions, selectEl)
},
autoselect: true,
showNoOptionsFound: true,
placeholder: 'Start typing to search',
templates: { suggestion: (value) => value },
onConfirm: (val) => {
const selectedResult = Array.from(selectEl.options).find(option => option.text === val)
if (selectedResult) {
selectedResult.selected = true
}
}
})
}
}

3
app/frontend/controllers/index.js

@ -19,8 +19,6 @@ import FilterLayoutController from './filter_layout_controller.js'
import TabsController from './tabs_controller.js'
import AddressSearchController from './address_search_controller.js'
application.register('accessible-autocomplete', AccessibleAutocompleteController)
application.register('conditional-filter', ConditionalFilterController)
application.register('conditional-question', ConditionalQuestionController)
@ -29,4 +27,3 @@ application.register('numeric-question', NumericQuestionController)
application.register('filter-layout', FilterLayoutController)
application.register('search', SearchController)
application.register('tabs', TabsController)
application.register('address-search', AddressSearchController)

15
app/models/derived_variables/lettings_log_variables.rb

@ -113,21 +113,6 @@ module DerivedVariables::LettingsLogVariables
self.previous_la_known = nil if is_renewal?
end
if form.start_year_2024_or_later?
if manual_address_entry_selected
self.uprn_known = 0
self.uprn_selection = nil
self.uprn_confirmed = nil
else
self.uprn_confirmed = 1 if uprn.present?
self.uprn_known = 1 if uprn.present?
reset_address_fields! if uprn.blank?
if uprn_changed?
self.uprn_selection = uprn
end
end
end
if is_renewal?
self.underoccupation_benefitcap = 2 if collection_start_year == 2021
self.voiddate = startdate

49
app/models/derived_variables/sales_log_variables.rb

@ -55,29 +55,27 @@ module DerivedVariables::SalesLogVariables
if uprn_known&.zero?
self.uprn = nil
if uprn_known_was == 1
reset_address_fields!
self.address_line1 = nil
self.address_line2 = nil
self.town_or_city = nil
self.county = nil
self.pcodenk = nil
self.postcode_full = nil
self.la = nil
end
end
if uprn_known == 1 && uprn_confirmed&.zero?
reset_address_fields!
self.uprn_known = 0
self.uprn_confirmed = nil
end
if form.start_year_2024_or_later?
if manual_address_entry_selected
self.uprn = nil
self.uprn_known = 0
self.uprn_selection = nil
self.uprn_confirmed = nil
else
self.uprn_confirmed = 1 if uprn.present?
self.uprn_known = 1 if uprn.present?
reset_address_fields! if uprn.blank?
if uprn_changed?
self.uprn_selection = uprn
end
end
self.address_line1 = nil
self.address_line2 = nil
self.town_or_city = nil
self.county = nil
self.pcodenk = nil
self.postcode_full = nil
self.la = nil
end
if form.start_year_2025_or_later? && is_bedsit?
@ -250,21 +248,4 @@ private
def prevten_was_social_housing?
[1, 2].include?(prevten) || [1, 2].include?(prevtenbuy2)
end
def reset_address_fields!
self.uprn = nil
self.uprn_known = nil
self.address_line1 = nil
self.address_line2 = nil
self.town_or_city = nil
self.county = nil
self.pcode1 = nil
self.pcode2 = nil
self.pcodenk = nil
self.address_line1_input = nil
self.postcode_full_input = nil
self.postcode_full = nil
self.is_la_inferred = nil
self.la = nil
end
end

9
app/models/form/lettings/pages/address_fallback.rb

@ -3,7 +3,14 @@ class Form::Lettings::Pages::AddressFallback < ::Form::Page
super
@id = "address"
@copy_key = "lettings.property_information.address"
@depends_on = [{ "is_supported_housing?" => false, "manual_address_entry_selected" => true }]
@depends_on = [
{ "is_supported_housing?" => false, "uprn_known" => nil, "uprn_selection" => "uprn_not_listed" },
{ "is_supported_housing?" => false, "uprn_known" => 0, "uprn_selection" => "uprn_not_listed" },
{ "is_supported_housing?" => false, "uprn_confirmed" => 0, "uprn_selection" => "uprn_not_listed" },
{ "is_supported_housing?" => false, "uprn_known" => nil, "address_options_present?" => false },
{ "is_supported_housing?" => false, "uprn_known" => 0, "address_options_present?" => false },
{ "is_supported_housing?" => false, "uprn_confirmed" => 0, "address_options_present?" => false },
]
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end

17
app/models/form/lettings/pages/address_search.rb

@ -1,17 +0,0 @@
class Form::Lettings::Pages::AddressSearch < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "address_search"
@copy_key = "sales.property_information.address_search"
@depends_on = [{ "is_supported_housing?" => false, "manual_address_entry_selected" => false }]
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def questions
@questions ||= [
Form::Lettings::Questions::AddressSearch.new(nil, nil, self),
]
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 12, 2025 => 16 }.freeze
end

44
app/models/form/lettings/questions/address_search.rb

@ -1,44 +0,0 @@
class Form::Lettings::Questions::AddressSearch < ::Form::Question
def initialize(id, hsh, page)
super
@id = "uprn"
@type = "address_search"
@copy_key = "lettings.property_information.address_search"
@plain_label = true
@bottom_guidance_partial = "address_search"
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
@hide_question_number_on_page = true
end
def answer_options(log = nil, _user = nil)
return {} unless ActiveRecord::Base.connected?
return {} unless log&.address_options&.any?
log.address_options.each_with_object({}) do |option, hash|
hash[option[:uprn]] = { "value" => "#{option[:address]} (#{option[:uprn]})" }
end
end
def get_extra_check_answer_value(log)
return unless log.uprn_known == 1
value = [
log.address_line1,
log.address_line2,
log.town_or_city,
log.county,
log.postcode_full,
(LocalAuthority.find_by(code: log.la)&.name if log.la.present?),
].select(&:present?)
return unless value.any?
"\n\n#{value.join("\n")}"
end
def displayed_answer_options(log, user = nil)
answer_options(log, user).transform_values { |value| value["value"] } || {}
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 12, 2025 => 16 }.freeze
end

1
app/models/form/lettings/questions/postcode_for_full_address.rb

@ -20,7 +20,6 @@ class Form::Lettings::Questions::PostcodeForFullAddress < ::Form::Question
@disable_clearing_if_not_routed_or_dynamic_answer_options = true
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
@hide_question_number_on_page = true
@bottom_guidance_partial = "address_fallback"
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 12, 2024 => 13, 2025 => 17 }.freeze

6
app/models/form/lettings/subsections/property_information.rb

@ -32,7 +32,11 @@ class Form::Lettings::Subsections::PropertyInformation < ::Form::Subsection
def uprn_questions
if form.start_year_2024_or_later?
[
Form::Lettings::Pages::AddressSearch.new(nil, nil, self),
Form::Lettings::Pages::Uprn.new(nil, nil, self),
Form::Lettings::Pages::UprnConfirmation.new(nil, nil, self),
Form::Lettings::Pages::AddressMatcher.new(nil, nil, self),
Form::Lettings::Pages::NoAddressFound.new(nil, nil, self), # soft validation
Form::Lettings::Pages::UprnSelection.new(nil, nil, self),
Form::Lettings::Pages::AddressFallback.new(nil, nil, self),
]
else

11
app/models/form/sales/pages/address_fallback.rb

@ -3,7 +3,14 @@ class Form::Sales::Pages::AddressFallback < ::Form::Page
super
@id = "address"
@copy_key = "sales.property_information.address"
@depends_on = [{ "manual_address_entry_selected" => true }]
@depends_on = [
{ "uprn_known" => nil, "uprn_selection" => "uprn_not_listed" },
{ "uprn_known" => 0, "uprn_selection" => "uprn_not_listed" },
{ "uprn_confirmed" => 0, "uprn_selection" => "uprn_not_listed" },
{ "uprn_known" => nil, "address_options_present?" => false },
{ "uprn_known" => 0, "address_options_present?" => false },
{ "uprn_confirmed" => 0, "address_options_present?" => false },
]
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
@ -17,5 +24,5 @@ class Form::Sales::Pages::AddressFallback < ::Form::Page
]
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 16, 2025 => 14 }.freeze
QUESTION_NUMBER_FROM_YEAR = { 2024 => 16, 2025 => 16 }.freeze
end

23
app/models/form/sales/pages/address_search.rb

@ -1,23 +0,0 @@
class Form::Sales::Pages::AddressSearch < ::Form::Page
def initialize(id, hsh, subsection)
super
@id = "address_search"
@copy_key = "sales.property_information.address_search"
@depends_on = [{ "manual_address_entry_selected" => false }]
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
end
def questions
@questions ||= [
Form::Sales::Questions::AddressSearch.new(nil, nil, self),
]
end
def skip_href(log = nil)
return unless log
"/#{log.log_type.dasherize}s/#{log.id}/property-number-of-bedrooms"
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 15, 2025 => 13 }.freeze
end

1
app/models/form/sales/pages/no_address_found.rb

@ -16,6 +16,7 @@ class Form::Sales::Pages::NoAddressFound < ::Form::Page
{ "uprn_known" => nil, "address_options_present?" => false },
{ "uprn_known" => 0, "address_options_present?" => false },
{ "uprn_confirmed" => 0, "address_options_present?" => false },
]
end

44
app/models/form/sales/questions/address_search.rb

@ -1,44 +0,0 @@
class Form::Sales::Questions::AddressSearch < ::Form::Question
def initialize(id, hsh, page)
super
@id = "uprn"
@type = "address_search"
@copy_key = "sales.property_information.address_search"
@plain_label = true
@bottom_guidance_partial = "address_search"
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
@hide_question_number_on_page = true
end
def answer_options(log = nil, _user = nil)
return {} unless ActiveRecord::Base.connected?
return {} unless log&.address_options&.any?
log.address_options.each_with_object({}) do |option, hash|
hash[option[:uprn]] = { "value" => "#{option[:address]} (#{option[:uprn]})" }
end
end
def get_extra_check_answer_value(log)
return unless log.uprn_known == 1
value = [
log.address_line1,
log.address_line2,
log.town_or_city,
log.county,
log.postcode_full,
(LocalAuthority.find_by(code: log.la)&.name if log.la.present?),
].select(&:present?)
return unless value.any?
"\n\n#{value.join("\n")}"
end
def displayed_answer_options(log, user = nil)
answer_options(log, user).transform_values { |value| value["value"] } || {}
end
QUESTION_NUMBER_FROM_YEAR = { 2024 => 15, 2025 => 13 }.freeze
end

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

@ -20,7 +20,6 @@ class Form::Sales::Questions::PostcodeForFullAddress < ::Form::Question
@disable_clearing_if_not_routed_or_dynamic_answer_options = true
@question_number = QUESTION_NUMBER_FROM_YEAR[form.start_date.year] || QUESTION_NUMBER_FROM_YEAR[QUESTION_NUMBER_FROM_YEAR.keys.max]
@hide_question_number_on_page = true
@bottom_guidance_partial = "address_fallback"
end
QUESTION_NUMBER_FROM_YEAR = { 2023 => 15, 2024 => 16, 2025 => 14 }.freeze

6
app/models/form/sales/subsections/property_information.rb

@ -24,7 +24,11 @@ class Form::Sales::Subsections::PropertyInformation < ::Form::Subsection
def uprn_questions
if form.start_year_2024_or_later?
[
Form::Sales::Pages::AddressSearch.new(nil, nil, self),
Form::Sales::Pages::Uprn.new(nil, nil, self),
Form::Sales::Pages::UprnConfirmation.new(nil, nil, self),
Form::Sales::Pages::AddressMatcher.new(nil, nil, self),
Form::Sales::Pages::NoAddressFound.new(nil, nil, self),
Form::Sales::Pages::UprnSelection.new(nil, nil, self),
Form::Sales::Pages::AddressFallback.new(nil, nil, self),
Form::Sales::Pages::PropertyLocalAuthority.new(nil, nil, self),
Form::Sales::Pages::Buyer1IncomeDiscountedMaxValueCheck.new("local_authority_buyer_1_income_max_value_check", nil, self, check_answers_card_number: nil),

18
app/models/log.rb

@ -75,7 +75,8 @@ class Log < ApplicationRecord
presenter = UprnDataPresenter.new(service.result)
self.uprn_known = 1
self.uprn_selection = uprn
self.uprn_confirmed = nil unless skip_update_uprn_confirmed
self.uprn_selection = nil
self.address_line1 = presenter.address_line1
self.address_line2 = presenter.address_line2
self.town_or_city = presenter.town_or_city
@ -125,27 +126,16 @@ class Log < ApplicationRecord
end
def address_options
if uprn.present?
service = UprnClient.new(uprn)
service.call
if service.result.blank? || service.error.present?
@address_options = []
return @address_options
end
presenter = UprnDataPresenter.new(service.result)
@address_options = [{ address: presenter.address, uprn: presenter.uprn }]
else
return @address_options if @address_options && @last_searched_address_string == address_string
return if address_string.blank?
if [address_line1_input, postcode_full_input].all?(&:present?)
@last_searched_address_string = address_string
service = AddressClient.new(address_string)
service.call
if service.result.blank? || service.error.present?
@address_options = []
return @address_options
return @answer_options
end
address_opts = []

7
app/services/address_client.rb

@ -7,9 +7,8 @@ class AddressClient
ADDRESS = "api.os.uk".freeze
PATH = "/search/places/v1/find".freeze
def initialize(address, options = {})
def initialize(address)
@address = address
@options = options
end
def call
@ -44,8 +43,8 @@ private
params = {
query: address,
key: ENV["OS_DATA_KEY"],
maxresults: @options[:maxresults] || 10,
minmatch: @options[:minmatch] || 0.4,
maxresults: 10,
minmatch: 0.4,
}
uri.query = URI.encode_www_form(params)
uri.to_s

1
app/services/bulk_upload/lettings/year2024/row_parser.rb

@ -1353,7 +1353,6 @@ private
attributes["address_line1_input"] = address_line1_input
attributes["postcode_full_input"] = postcode_full
attributes["select_best_address_match"] = true if field_16.blank?
attributes["manual_address_entry_selected"] = field_16.blank?
end
attributes

1
app/services/bulk_upload/lettings/year2025/row_parser.rb

@ -1348,7 +1348,6 @@ private
attributes["address_line1_input"] = address_line1_input
attributes["postcode_full_input"] = postcode_full
attributes["select_best_address_match"] = true if field_18.blank?
attributes["manual_address_entry_selected"] = field_18.blank?
end
attributes

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

@ -986,7 +986,6 @@ private
attributes["address_line1_input"] = address_line1_input
attributes["postcode_full_input"] = postcode_full
attributes["select_best_address_match"] = true if field_22.blank?
attributes["manual_address_entry_selected"] = field_22.blank?
attributes["ethnic_group2"] = infer_buyer2_ethnic_group_from_ethnic
attributes["ethnicbuy2"] = field_40

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

@ -961,7 +961,6 @@ private
attributes["address_line1_input"] = address_line1_input
attributes["postcode_full_input"] = postcode_full
attributes["select_best_address_match"] = true if field_16.blank?
attributes["manual_address_entry_selected"] = field_16.blank?
attributes["ethnic_group2"] = infer_buyer2_ethnic_group_from_ethnic
attributes["ethnicbuy2"] = field_37

22
app/services/csv/lettings_log_csv_service.rb

@ -208,11 +208,6 @@ module Csv
3 => "Intermediate Rent",
}.freeze
UPRN_KNOWN_LABELS = {
0 => "No",
1 => "Yes",
}.freeze
LABELS = {
"lettype" => LETTYPE_LABELS,
"irproduct" => IRPRODUCT_LABELS,
@ -220,7 +215,6 @@ module Csv
"newprop" => NEWPROP_LABELS,
"incref" => INCREF_LABELS,
"renttype" => RENTTYPE_LABELS,
"uprn_known" => UPRN_KNOWN_LABELS,
}.freeze
CONVENTIONAL_YES_NO_ATTRIBUTES = %w[illness_type_1 illness_type_2 illness_type_3 illness_type_4 illness_type_5 illness_type_6 illness_type_7 illness_type_8 illness_type_9 illness_type_10 refused cbl cap chr accessible_register letting_allocation_none housingneeds_a housingneeds_b housingneeds_c housingneeds_d housingneeds_e housingneeds_f housingneeds_g housingneeds_h has_benefits nocharge postcode_known].freeze
@ -255,18 +249,6 @@ module Csv
"letting_allocation_unknown" => %w[letting_allocation_none],
}.freeze
ATTRIBUTE_MAPPINGS_2024 = {
"uprn" => %w[uprn_known uprn],
}.freeze
def attribute_mappings
if @year >= 2024
ATTRIBUTE_MAPPINGS.merge(ATTRIBUTE_MAPPINGS_2024)
else
ATTRIBUTE_MAPPINGS
end
end
ORDERED_ADDRESS_FIELDS = %w[uprn address_line1 address_line2 town_or_city county postcode_full is_la_inferred la_label la uprn_known uprn_selection address_search_value_check address_line1_input postcode_full_input address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered].freeze
SUPPORT_ONLY_ATTRIBUTES = %w[postcode_known is_la_inferred totchild totelder totadult net_income_known previous_la_known is_previous_la_inferred age1_known age2_known age3_known age4_known age5_known age6_known age7_known age8_known details_known_2 details_known_3 details_known_4 details_known_5 details_known_6 details_known_7 details_known_8 wrent wscharge wpschrge wsupchrg wtcharge wtshortfall old_form_id old_id tshortfall_known hhtype la prevloc updated_by_id uprn_confirmed address_line1_input postcode_full_input uprn_selection address_line1_as_entered address_line2_as_entered town_or_city_as_entered county_as_entered postcode_full_as_entered la_as_entered created_by].freeze
@ -297,10 +279,10 @@ module Csv
ordered_questions.flat_map do |question|
if question.type == "checkbox"
question.answer_options.keys.reject { |key| key == "divider" }.map { |key|
attribute_mappings.fetch(key, key)
ATTRIBUTE_MAPPINGS.fetch(key, key)
}.flatten
else
attribute_mappings.fetch(question.id, question.id)
ATTRIBUTE_MAPPINGS.fetch(question.id, question.id)
end
end
end

14
app/services/csv/sales_log_csv_service.rb

@ -152,15 +152,6 @@ module Csv
"uprn_confirmed" => "UPRNCONFIRMED",
}.freeze
UPRN_CONFIRMED_LABELS = {
0 => "No",
1 => "Yes",
}.freeze
LABELS = {
"uprn_confirmed" => UPRN_CONFIRMED_LABELS,
}.freeze
def formatted_attribute_headers
return @attributes unless @user.support?
@ -217,9 +208,6 @@ module Csv
unless @user.support? && @year >= 2024
mappings["postcode_full"] = %w[pcode1 pcode2]
end
if @year >= 2024
mappings["uprn"] = %w[uprn uprn_confirmed address_line1_input postcode_full_input uprn_selection]
end
mappings
end
@ -292,8 +280,6 @@ module Csv
end
def get_label(value, attribute, log)
return LABELS[attribute][value] if LABELS.key?(attribute)
log.form
.get_question(attribute, log)
&.label_from_value(value)

8
app/services/uprn_data_presenter.rb

@ -55,12 +55,4 @@ class UprnDataPresenter
def result_from_lpi?
data["LPI_KEY"].present?
end
def uprn
data["UPRN"]
end
def address
data["ADDRESS"]
end
end

24
app/views/form/_address_search_question.html.erb

@ -1,24 +0,0 @@
<% selected = @log.public_send(question.id) || "" %>
<% answers = question.displayed_answer_options(@log, current_user).map { |key, value| OpenStruct.new(id: key, name: select_option_name(value), resource: value) } %>
<%= render partial: "form/guidance/#{question.top_guidance_partial}" if question.top_guidance? %>
<%= f.govuk_select(question.id.to_sym,
label: legend(question, page_header, conditional),
"data-controller": "address-search",
"data-info": { search_url: address_search_url }.to_json,
caption: caption(caption_text, page_header, conditional),
hint: { text: question.hint_text&.html_safe }) do %>
<% if answers.any? %>
<% answers.each do |answer| %>
<option value="<%= answer.id %>"
data-synonyms="<%= answer_option_synonyms(answer.resource) %>"
data-append="<%= answer_option_append(answer.resource) %>"
data-hint="<%= answer_option_hint(answer.resource) %>"
<%= question.answer_selected?(@log, answer) ? "selected" : "" %>><%= answer.name || answer.resource %></option>
<% end %>
<% else %>
<option value="" disabled>Javascript is disabled. Please enter the address manually.</option>
<% end %>
<% end %>
<%= render partial: "form/guidance/#{question.bottom_guidance_partial}" if question.bottom_guidance? %>

5
app/views/form/_select_question.html.erb

@ -1,3 +1,4 @@
<% selected = @log.public_send(question.id) || "" %>
<% answers = question.displayed_answer_options(@log, current_user).map { |key, value| OpenStruct.new(id: key, name: select_option_name(value), resource: value) } %>
<%= render partial: "form/guidance/#{question.top_guidance_partial}" if question.top_guidance? %>
@ -7,7 +8,6 @@
"data-controller": "accessible-autocomplete",
caption: caption(caption_text, page_header, conditional),
hint: { text: question.hint_text&.html_safe }) do %>
<% if answers.any? %>
<% answers.each do |answer| %>
<option value="<%= answer.id %>"
data-synonyms="<%= answer_option_synonyms(answer.resource) %>"
@ -15,9 +15,6 @@
data-hint="<%= answer_option_hint(answer.resource) %>"
<%= question.answer_selected?(@log, answer) ? "selected" : "" %>><%= answer.name || answer.resource %></option>
<% end %>
<% else %>
<option value="" disabled></option>
<% end %>
<% end %>
<%= render partial: "form/guidance/#{question.bottom_guidance_partial}" if question.bottom_guidance? %>

3
app/views/form/guidance/_address_fallback.html.erb

@ -1,3 +0,0 @@
<div class="govuk-button-group">
<%= govuk_link_to "Clear address and search instead", address_search_input_path(@log.log_type, @log.id), class: "govuk-button govuk-button--secondary" %>
</div>

7
app/views/form/guidance/_address_search.html.erb

@ -1,7 +0,0 @@
<%= govuk_details(summary_text: I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_search.title")) do %>
<%= I18n.t("forms.#{@log.form.start_date.year}.#{@log.form.type}.guidance.address_search.content").html_safe %>
<% end %>
<div class="govuk-button-group">
<%= govuk_link_to "Enter the address manually instead", address_manual_input_path(@log.log_type, @log.id), class: "govuk-button govuk-button--secondary" %>
</div>

7
config/locales/forms/2024/lettings/guidance.en.yml

@ -61,10 +61,3 @@ en:
<li>child benefit</li>
<li>council tax support</li>
</ul>"
address_search:
title: "Can’t find the address you’re looking for?"
content: "<ul class=\"govuk-list govuk-list--bullet\">
<li>Some properties may not be available yet e.g. new builds; you might need to enter them manually instead</li>
<li>For UPRN (Unique Property Reference Number), please enter the full value exactly</li>
</ul>"

7
config/locales/forms/2024/lettings/property_information.en.yml

@ -50,13 +50,6 @@ en:
hint_text: ""
question_text: "Select the correct address"
address_search:
page_header: "What is the property's address?"
check_answer_label: "Address"
check_answer_prompt: "Enter address or UPRN"
hint_text: "For example, '1 Victoria Road' or '10010457355'"
question_text: "Enter address or UPRN"
address:
page_header: "What is the property's address?"
address_line1:

7
config/locales/forms/2024/sales/guidance.en.yml

@ -44,10 +44,3 @@ en:
privacy_notice_buyer:
content: "Make sure the buyer has seen or been given access to %{privacy_notice_link} before completing this log. This is a legal requirement under data protection legislation."
privacy_notice_link_text: "the Ministry of Housing, Communities and Local Government (MHCLG) privacy notice"
address_search:
title: "Can’t find the address you’re looking for?"
content: "<ul class=\"govuk-list govuk-list--bullet\">
<li>Some properties may not be available yet e.g. new builds; you might need to enter them manually instead</li>
<li>For UPRN (Unique Property Reference Number), please enter the full value exactly</li>
</ul>"

7
config/locales/forms/2024/sales/property_information.en.yml

@ -43,13 +43,6 @@ en:
hint_text: ""
question_text: "Select the correct address"
address_search:
page_header: "What is the property's address?"
check_answer_label: "Address"
check_answer_prompt: "Enter address or UPRN"
hint_text: "For example, '1 Victoria Road' or '10010457355'"
question_text: "Enter address or UPRN"
address:
page_header: "What is the property's address?"
address_line1:

7
config/locales/forms/2025/lettings/guidance.en.yml

@ -61,10 +61,3 @@ en:
<li>child benefit</li>
<li>council tax support</li>
</ul>"
address_search:
title: "Can’t find the address you’re looking for?"
content: "<ul class=\"govuk-list govuk-list--bullet\">
<li>Some properties may not be available yet e.g. new builds; you might need to enter them manually instead</li>
<li>For UPRN (Unique Property Reference Number), please enter the full value exactly</li>
</ul>"

45
config/locales/forms/2025/lettings/property_information.en.yml

@ -10,12 +10,45 @@ en:
hint_text: ""
question_text: "Is this the first time the property has been let as social housing?"
address_search:
page_header: "What is the property's address?"
check_answer_label: "Address"
check_answer_prompt: "Enter address or UPRN"
hint_text: "For example, '1 Victoria Road' or '10010457355'"
question_text: "Enter address or UPRN"
uprn:
page_header: ""
uprn_known:
check_answer_label: "UPRN known"
check_answer_prompt: "Enter UPRN if known"
hint_text: "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example UPRN is 10010457355.<br><br>The UPRN may not be the same as the property reference assigned by your organisation.<br><br>If you don’t know the UPRN you can enter the address of the property instead on the next screen."
question_text: "Do you know the property's UPRN?"
uprn:
check_answer_label: "UPRN"
check_answer_prompt: ""
hint_text: ""
question_text: "What is the property's UPRN?"
uprn_confirmed:
page_header: "We found an address that might be this property"
check_answer_label: "Is this the right address?"
check_answer_prompt: "Tell us if this is the right address"
hint_text: ""
question_text: "Is this the property address?"
address_matcher:
page_header: "Find an address"
address_line1_input:
check_answer_label: "Find address"
check_answer_prompt: "Try find address"
hint_text: ""
question_text: "Address line 1"
postcode_full_input:
check_answer_label: ""
check_answer_prompt: ""
hint_text: ""
question_text: "Postcode"
uprn_selection:
page_header: "We found an address that might be this property"
check_answer_label: "Select correct address"
check_answer_prompt: "Select correct address"
hint_text: ""
question_text: "Select the correct address"
address:
page_header: "What is the property's address?"

7
config/locales/forms/2025/sales/guidance.en.yml

@ -44,10 +44,3 @@ en:
privacy_notice_buyer:
content: "Make sure the buyer has seen or been given access to %{privacy_notice_link} before completing this log. This is a legal requirement under data protection legislation."
privacy_notice_link_text: "the Ministry of Housing, Communities and Local Government (MHCLG) privacy notice"
address_search:
title: "Can’t find the address you’re looking for?"
content: "<ul class=\"govuk-list govuk-list--bullet\">
<li>Some properties may not be available yet e.g. new builds; you might need to enter them manually instead</li>
<li>For UPRN (Unique Property Reference Number), please enter the full value exactly</li>
</ul>"

45
config/locales/forms/2025/sales/property_information.en.yml

@ -3,12 +3,45 @@ en:
2025:
sales:
property_information:
address_search:
page_header: "What is the property's address?"
check_answer_label: "Address"
check_answer_prompt: "Enter address or UPRN"
hint_text: "For example, '1 Victoria Road' or '10010457355'"
question_text: "Enter address or UPRN"
uprn:
page_header: ""
uprn_known:
check_answer_label: "UPRN known"
check_answer_prompt: "Enter UPRN if known"
hint_text: "The Unique Property Reference Number (UPRN) is a unique number system created by Ordnance Survey and used by housing providers and various industries across the UK. An example UPRN is 10010457355.<br><br>The UPRN may not be the same as the property reference assigned by your organisation.<br><br>If you don’t know the UPRN you can enter the address of the property instead on the next screen."
question_text: "Do you know the property's UPRN?"
uprn:
check_answer_label: "UPRN"
check_answer_prompt: ""
hint_text: ""
question_text: "What is the property's UPRN?"
uprn_confirmed:
page_header: "We found an address that might be this property"
check_answer_label: "Is this the right address?"
check_answer_prompt: "Tell us if this is the right address"
hint_text: ""
question_text: "Is this the property address?"
address_matcher:
page_header: "Find an address"
address_line1_input:
check_answer_label: "Find address"
check_answer_prompt: "Try find address"
hint_text: ""
question_text: "Address line 1"
postcode_full_input:
check_answer_label: ""
check_answer_prompt: ""
hint_text: ""
question_text: "Postcode"
uprn_selection:
page_header: "We found an address that might be this property"
check_answer_label: "Select correct address"
check_answer_prompt: "Select correct address"
hint_text: ""
question_text: "Select the correct address"
address:
page_header: "What is the property's address?"

14
config/locales/validations/sales/property_information.en.yml

@ -7,7 +7,7 @@ en:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match."
invalid: "Enter a postcode in the correct format, for example AA1 1AA."
not_in_england: "It looks like you have entered a postcode outside of England. Only create logs for sales in England."
not_in_england: "It looks like you have entered a postcode outside of England - only submit Lettings forms for Lettings that occur in England"
ppostcode_full:
postcode_must_match_previous:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
@ -21,7 +21,7 @@ en:
joint_purchase: "Buyers’ last accommodation and discounted ownership postcodes must match."
not_joint_purchase: "Buyer’s last accommodation and discounted ownership postcodes must match."
invalid: "UPRN must be 12 digits or less."
not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England."
not_in_england: "It looks like you have an entered a postcode outside of England. Only create logs for lettings in England."
beds:
bedsits_have_max_one_bedroom: "Number of bedrooms must be 1 if the property is a bedsit."
proptype:
@ -29,11 +29,11 @@ en:
uprn_known:
invalid: "You must answer UPRN known?"
la:
not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England."
not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England."
uprn_confirmation:
not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England."
not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England."
uprn_selection:
not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England."
not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England."
saledate:
postcode_not_in_england: "It looks like you have entered a postcode outside of England. Only create logs for sales in England."
address_not_in_england: "It looks like you have entered an address outside of England. Only create logs for sales in England."
postcode_not_in_england: "It looks like you have an entered a postcode outside of England. Only create logs for lettings in England."
address_not_in_england: "It looks like you have entered an address outside of England. Only create logs for lettings in England."

4
config/routes.rb

@ -39,10 +39,6 @@ Rails.application.routes.draw do
get "/data-sharing-agreement", to: "content#data_sharing_agreement"
get "/service-moved", to: "maintenance#service_moved"
get "/service-unavailable", to: "maintenance#service_unavailable"
get "/address-search", to: "address_search#index"
get "/address-search/current", to: "address_search#current"
get "/address-search/manual-input/:log_type/:log_id", to: "address_search#manual_input", as: "address_manual_input"
get "/address-search/search-input/:log_type/:log_id", to: "address_search#search_input", as: "address_search_input"
get "collection-resources", to: "collection_resources#index"
get "/collection-resources/:log_type/:year/:resource_type/download", to: "collection_resources#download_mandatory_collection_resource", as: :download_mandatory_collection_resource

6
db/migrate/20250219122817_add_manual_address_entry_selected_to_logs.rb

@ -1,6 +0,0 @@
class AddManualAddressEntrySelectedToLogs < ActiveRecord::Migration[7.2]
def change
add_column :sales_logs, :manual_address_entry_selected, :boolean, default: false
add_column :lettings_logs, :manual_address_entry_selected, :boolean, default: false
end
end

4
db/schema.rb

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2025_02_19_122817) do
ActiveRecord::Schema[7.2].define(version: 2025_01_10_150609) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -373,7 +373,6 @@ ActiveRecord::Schema[7.2].define(version: 2025_02_19_122817) do
t.integer "partner_under_16_value_check"
t.integer "multiple_partners_value_check"
t.bigint "created_by_id"
t.boolean "manual_address_entry_selected", default: false
t.index ["assigned_to_id"], name: "index_lettings_logs_on_assigned_to_id"
t.index ["bulk_upload_id"], name: "index_lettings_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_lettings_logs_on_created_by_id"
@ -770,7 +769,6 @@ ActiveRecord::Schema[7.2].define(version: 2025_02_19_122817) do
t.decimal "mrentprestaircasing", precision: 10, scale: 2
t.datetime "lasttransaction"
t.datetime "initialpurchase"
t.boolean "manual_address_entry_selected", default: false
t.index ["assigned_to_id"], name: "index_sales_logs_on_assigned_to_id"
t.index ["bulk_upload_id"], name: "index_sales_logs_on_bulk_upload_id"
t.index ["created_by_id"], name: "index_sales_logs_on_created_by_id"

9
spec/factories/lettings_log.rb

@ -6,7 +6,6 @@ FactoryBot.define do
managing_organisation { assigned_to.organisation }
created_at { Time.zone.today }
updated_at { Time.zone.today }
manual_address_entry_selected { true }
before(:create) do |log, _evaluator|
if log.period && !log.managing_organisation.organisation_rent_periods.exists?(rent_period: log.period)
@ -167,11 +166,13 @@ FactoryBot.define do
town_or_city { Faker::Address.city }
ppcodenk { 1 }
tshortfall_known { 1 }
after(:build) do |log, evaluator|
after(:build) do |log, _evaluator|
if log.startdate >= Time.zone.local(2024, 4, 1)
log.address_line1_input = log.address_line1
log.postcode_full_input = log.postcode_full
log.nationality_all_group = 826
log.uprn = evaluator.uprn || "10033558653"
log.uprn_selection = evaluator.uprn_selection || "10033558653"
log.uprn = "10033558653"
log.uprn_selection = 1
end
end
end

10
spec/factories/sales_log.rb

@ -8,8 +8,6 @@ FactoryBot.define do
managing_organisation { assigned_to.organisation }
created_at { Time.zone.now }
updated_at { Time.zone.now }
manual_address_entry_selected { true }
trait :in_progress do
purchid { "PC123" }
ownershipsch { 2 }
@ -168,12 +166,14 @@ FactoryBot.define do
nationalbuy2 { 13 }
buy2living { 3 }
proplen_asked { 1 }
after(:build) do |log, evaluator|
after(:build) do |log, _evaluator|
if log.saledate >= Time.zone.local(2024, 4, 1)
log.address_line1_input = log.address_line1
log.postcode_full_input = log.postcode_full
log.nationality_all_group = 826
log.nationality_all_buyer2_group = 826
log.uprn = evaluator.uprn || "10033558653"
log.uprn_selection = evaluator.uprn_selection || "10033558653"
log.uprn = "10033558653"
log.uprn_selection = 1
end
if log.saledate >= Time.zone.local(2025, 4, 1)
log.relat2 = "X" if log.relat2 == "C"

45
spec/features/form/address_search_spec.rb

@ -1,45 +0,0 @@
require "rails_helper"
require_relative "helpers"
RSpec.describe "Address Search" do
include Helpers
let(:user) { FactoryBot.create(:user) }
let(:sales_log) do
FactoryBot.create(
:sales_log,
:shared_ownership_setup_complete,
assigned_to: user,
manual_address_entry_selected: false,
)
end
before do
sign_in user
end
context "when using address search feature" do
before do
visit("/sales-logs/#{sales_log.id}/address-search")
end
it "allows searching by a UPRN", js: true do
find("#sales-log-uprn-field").click.native.send_keys("1", "0", "0", "3", "3", "5", "4", "4", "6", "1", "4", :down)
expect(find("#sales-log-uprn-field").value).to eq("10033544614")
end
it "allows searching by address", js: true do
find("#sales-log-uprn-field").click.native.send_keys("S", "W", "1", "5", :down, :enter)
expect(find("#sales-log-uprn-field").value).to eq("SW15")
end
it "displays the placeholder text", js: true do
expect(find("#sales-log-uprn-field")["placeholder"]).to eq("Start typing to search")
end
it "displays correct bottom guidance text" do
find("span.govuk-details__summary-text", text: "Can’t find the address you’re looking for?").click
expect(page).to have_content("Some properties may not be available yet e.g. new builds; you might need to enter them manually instead")
expect(page).to have_content("For UPRN (Unique Property Reference Number), please enter the full value exactly")
end
end
end

60
spec/features/form/form_navigation_spec.rb

@ -186,4 +186,64 @@ RSpec.describe "Form Navigation" do
expect(page).to have_current_path("/lettings-logs/#{id}/duplicate-logs?original_log_id=#{id}")
end
end
describe "searching for an address" do
let(:now) { Time.zone.local(2024, 5, 1) }
context "with a lettings log" do
let(:lettings_log) { create(:lettings_log, :setup_completed, startdate: Time.zone.local(2024, 5, 5), assigned_to: user) }
before do
stub_request(:get, /api\.os\.uk/)
.to_return(status: 200, body: { results: [{ DPA: { MATCH: 0.9, BUILDING_NAME: "result address line 1", POST_TOWN: "result town or city", POSTCODE: "AA1 1AA", UPRN: "12345" } }] }.to_json, headers: {})
end
it "allows searching for an address" do
visit("lettings-logs/#{id}/address-matcher")
fill_in("lettings-log-address-line1-input-field", with: "address")
fill_in("lettings-log-postcode-full-input-field", with: "A1 1AA")
click_button(text: "Search")
expect(page).to have_current_path("/lettings-logs/#{id}/uprn-selection")
end
it "allows searching for an address from check your answers page" do
visit("lettings-logs/#{id}/address-matcher?referrer=check_answers")
fill_in("lettings-log-address-line1-input-field", with: "address")
fill_in("lettings-log-postcode-full-input-field", with: "A1 1AA")
click_button(text: "Search")
expect(page).to have_current_path("/lettings-logs/#{id}/uprn-selection?referrer=check_answers&unanswered_pages=property_local_authority")
choose("lettings-log-uprn-selection-12345-field", allow_label_click: true)
click_button(text: "Save changes")
expect(page).to have_current_path("/lettings-logs/#{id}/property-information/check-answers")
end
end
context "with a sales log" do
let(:sales_log) { create(:sales_log, :outright_sale_setup_complete, saledate: Time.zone.local(2024, 5, 5), assigned_to: user) }
before do
stub_request(:get, /api\.os\.uk/)
.to_return(status: 200, body: { results: [{ DPA: { MATCH: 0.9, BUILDING_NAME: "result address line 1", POST_TOWN: "result town or city", POSTCODE: "AA1 1AA", UPRN: "12345" } }] }.to_json, headers: {})
end
it "allows searching for an address" do
visit("sales-logs/#{sales_log.id}/address-matcher")
fill_in("sales-log-address-line1-input-field", with: "address")
fill_in("sales-log-postcode-full-input-field", with: "A1 1AA")
click_button(text: "Search")
expect(page).to have_current_path("/sales-logs/#{sales_log.id}/uprn-selection")
end
it "allows searching for an address from check your answers page" do
visit("sales-logs/#{sales_log.id}/address-matcher?referrer=check_answers")
fill_in("sales-log-address-line1-input-field", with: "address")
fill_in("sales-log-postcode-full-input-field", with: "A1 1AA")
click_button(text: "Search")
expect(page).to have_current_path("/sales-logs/#{sales_log.id}/uprn-selection?referrer=check_answers&unanswered_pages=property_local_authority")
choose("sales-log-uprn-selection-12345-field", allow_label_click: true)
click_button(text: "Save changes")
expect(page).to have_current_path("/sales-logs/#{sales_log.id}/property-information/check-answers")
end
end
end
end

375
spec/features/lettings_log_spec.rb

@ -729,5 +729,380 @@ RSpec.describe "Lettings Log Features" do
expect(duplicate_log.duplicate_set_id).to be_nil
end
end
context "when filling out address fields" do
let(:lettings_log) { create(:lettings_log, :setup_completed, assigned_to: user) }
before do
body = {
results: [
{
DPA: {
"POSTCODE": "AA1 1AA",
"POST_TOWN": "Bristol",
"ORGANISATION_NAME": "Some place",
},
},
],
}.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=111")
.to_return(status: 200, body:, headers: {})
body = { results: [{ DPA: { UPRN: "111" } }] }.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/find?query=Address+line+1%2C+AA1+1AA&key=OS_DATA_KEY&maxresults=10&minmatch=0.4")
.to_return(status: 200, body:, headers: {})
WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/AA11AA")
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"AA1 1AA\",\"admin_district\":\"Westminster\",\"codes\":{\"admin_district\":\"E09000033\"}}}", headers: {})
WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/AA12AA")
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"AA1 2AA\",\"admin_district\":\"Wigan\",\"codes\":{\"admin_district\":\"E08000010\"}}}", headers: {})
body = { results: [] }.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/find?query=Address+line+1%2C+AA1+1AB&key=OS_DATA_KEY&maxresults=10&minmatch=0.4")
.to_return(status: 200, body:, headers: {})
visit("/lettings-logs/#{lettings_log.id}/uprn")
end
context "and uprn is known and answered" do
before do
choose "Yes"
fill_in("lettings_log[uprn]", with: "111")
click_button("Save and continue")
end
context "and uprn is confirmed" do
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(1) # yes
expect(lettings_log.uprn).to eq("111")
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 1AA")
expect(lettings_log.address_line1).to eq("Some Place")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq("Bristol")
expect(lettings_log.address_line1_input).to eq(nil)
expect(lettings_log.postcode_full_input).to eq(nil)
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E09000033")
choose "Yes"
click_button("Save and continue")
lettings_log.reload
expect(lettings_log.uprn_known).to eq(1) # yes
expect(lettings_log.uprn).to eq("111")
expect(lettings_log.uprn_confirmed).to eq(1) # yes
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 1AA")
expect(lettings_log.address_line1).to eq("Some Place")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq("Bristol")
expect(lettings_log.address_line1_input).to eq(nil)
expect(lettings_log.postcode_full_input).to eq(nil)
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E09000033")
end
context "and changes to uprn not known" do
it "sets correct address fields" do
visit("/lettings-logs/#{lettings_log.id}/uprn")
choose "No"
click_button("Save and continue")
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq(nil)
expect(lettings_log.postcode_full_input).to eq(nil)
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq(nil)
end
end
end
context "and uprn is not confirmed" do
before do
choose "No, I want to search for the address instead"
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq(nil)
expect(lettings_log.postcode_full_input).to eq(nil)
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq(nil)
end
end
end
context "and uprn is not known" do
before do
choose "No"
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq(nil)
expect(lettings_log.postcode_full_input).to eq(nil)
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq(nil)
end
context "and the address is not found" do
it "sets correct address fields" do
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1 1AB")
click_button("Search")
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AB")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq(nil)
click_button("Confirm and continue")
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AB")
expect(lettings_log.address_search_value_check).to eq(0)
expect(lettings_log.la).to eq(nil)
end
end
context "and address is found, re-searched and not found" do
before do
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
visit("/lettings-logs/#{lettings_log.id}/address-matcher")
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1 1AB")
click_button("Search")
end
it "routes to the correct page" do
expect(page).to have_current_path("/lettings-logs/#{lettings_log.id}/no-address-found")
end
end
context "and the user selects 'address_not_listed'" do
before do
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
choose "The address is not listed, I want to enter the address manually"
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq("uprn_not_listed")
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 1AA")
expect(lettings_log.address_line1).to eq("Address line 1")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AA")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E09000033")
end
context "and the user enters a new address manually" do
context "without changing a valid postcode" do
before do
fill_in("lettings_log[town_or_city]", with: "Town")
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq("uprn_not_listed")
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 1AA")
expect(lettings_log.address_line1).to eq("Address line 1")
expect(lettings_log.address_line2).to eq("")
expect(lettings_log.town_or_city).to eq("Town")
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AA")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E09000033")
end
end
context "with changing the postcode" do
before do
fill_in("lettings_log[town_or_city]", with: "Town")
fill_in("lettings_log[postcode_full]", with: "AA12AA")
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq("uprn_not_listed")
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 2AA")
expect(lettings_log.address_line1).to eq("Address line 1")
expect(lettings_log.address_line2).to eq("")
expect(lettings_log.town_or_city).to eq("Town")
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AA")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E08000010")
end
end
end
end
context "and the user selects 'address_not_listed' when partial postcode is entered" do
before do
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1")
click_button("Search")
choose "The address is not listed, I want to enter the address manually"
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(0) # no
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq("uprn_not_listed")
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq("Address line 1")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq(nil)
end
end
context "and the user selects 'address_not_listed' and then changes their mind and selects an address" do
before do
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
choose "The address is not listed, I want to enter the address manually"
click_button("Save and continue")
visit("/lettings-logs/#{lettings_log.id}/uprn-selection")
choose("lettings-log-uprn-selection-111-field", allow_label_click: true)
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(1)
expect(lettings_log.uprn).to eq("111")
expect(lettings_log.uprn_confirmed).to eq(1)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 1AA")
expect(lettings_log.address_line1).to eq("Some Place")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq("Bristol")
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AA")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E09000033")
end
end
context "and possible addresses found and selected" do
before do
fill_in("lettings_log[address_line1_input]", with: "Address line 1")
fill_in("lettings_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
choose("lettings-log-uprn-selection-111-field", allow_label_click: true)
click_button("Save and continue")
end
it "sets correct address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(1)
expect(lettings_log.uprn).to eq("111")
expect(lettings_log.uprn_confirmed).to eq(1)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("AA1 1AA")
expect(lettings_log.address_line1).to eq("Some Place")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq("Bristol")
expect(lettings_log.address_line1_input).to eq("Address line 1")
expect(lettings_log.postcode_full_input).to eq("AA1 1AA")
expect(lettings_log.address_search_value_check).to eq(nil)
expect(lettings_log.la).to eq("E09000033")
end
end
end
end
end
end

375
spec/features/sales_log_spec.rb

@ -334,6 +334,381 @@ RSpec.describe "Sales Log Features" do
expect(page).to have_current_path("/sales-logs/bulk-uploads")
end
end
context "when filling out address fields" do
let(:sales_log) { create(:sales_log, :shared_ownership_setup_complete, assigned_to: user) }
before do
body = {
results: [
{
DPA: {
"POSTCODE": "AA1 1AA",
"POST_TOWN": "Bristol",
"ORGANISATION_NAME": "Some place",
},
},
],
}.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key=OS_DATA_KEY&uprn=111")
.to_return(status: 200, body:, headers: {})
body = { results: [{ DPA: { UPRN: "111" } }] }.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/find?query=Address+line+1%2C+AA1+1AA&key=OS_DATA_KEY&maxresults=10&minmatch=0.4")
.to_return(status: 200, body:, headers: {})
WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/AA11AA")
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"AA1 1AA\",\"admin_district\":\"Westminster\",\"codes\":{\"admin_district\":\"E09000033\"}}}", headers: {})
WebMock.stub_request(:get, "https://api.postcodes.io/postcodes/AA12AA")
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"postcode\":\"AA1 2AA\",\"admin_district\":\"Wigan\",\"codes\":{\"admin_district\":\"E08000010\"}}}", headers: {})
body = { results: [] }.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/find?query=Address+line+1%2C+AA1+1AB&key=OS_DATA_KEY&maxresults=10&minmatch=0.4")
.to_return(status: 200, body:, headers: {})
visit("/sales-logs/#{sales_log.id}/uprn")
end
context "and uprn is known and answered" do
before do
choose "Yes"
fill_in("sales_log[uprn]", with: "111")
click_button("Save and continue")
end
context "and uprn is confirmed" do
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(1) # yes
expect(sales_log.uprn).to eq("111")
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 1AA")
expect(sales_log.address_line1).to eq("Some Place")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq("Bristol")
expect(sales_log.address_line1_input).to eq(nil)
expect(sales_log.postcode_full_input).to eq(nil)
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E09000033")
choose "Yes"
click_button("Save and continue")
sales_log.reload
expect(sales_log.uprn_known).to eq(1) # yes
expect(sales_log.uprn).to eq("111")
expect(sales_log.uprn_confirmed).to eq(1) # yes
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 1AA")
expect(sales_log.address_line1).to eq("Some Place")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq("Bristol")
expect(sales_log.address_line1_input).to eq(nil)
expect(sales_log.postcode_full_input).to eq(nil)
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E09000033")
end
context "and changes to uprn not known" do
it "sets correct address fields" do
visit("/sales-logs/#{sales_log.id}/uprn")
choose "No"
click_button("Save and continue")
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq(nil)
expect(sales_log.postcode_full_input).to eq(nil)
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq(nil)
end
end
end
context "and uprn is not confirmed" do
before do
choose "No, I want to search for the address instead"
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq(nil)
expect(sales_log.postcode_full_input).to eq(nil)
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq(nil)
end
end
end
context "and uprn is not known" do
before do
choose "No"
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq(nil)
expect(sales_log.postcode_full_input).to eq(nil)
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq(nil)
end
context "and the address is not found" do
it "sets correct address fields" do
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "AA1 1AB")
click_button("Search")
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AB")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq(nil)
click_button("Confirm and continue")
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AB")
expect(sales_log.address_search_value_check).to eq(0)
expect(sales_log.la).to eq(nil)
end
end
context "and address is found, re-searched and not found" do
before do
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
visit("/sales-logs/#{sales_log.id}/address-matcher")
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "AA1 1AB")
click_button("Search")
end
it "routes to the correct page" do
expect(page).to have_current_path("/sales-logs/#{sales_log.id}/no-address-found")
end
end
context "and the user selects 'address_not_listed'" do
before do
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
choose "The address is not listed, I want to enter the address manually"
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq("uprn_not_listed")
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 1AA")
expect(sales_log.address_line1).to eq("Address line 1")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AA")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E09000033")
end
context "and the user enters a new address manually" do
context "without changing a valid postcode" do
before do
fill_in("sales_log[town_or_city]", with: "Town")
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq("uprn_not_listed")
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 1AA")
expect(sales_log.address_line1).to eq("Address line 1")
expect(sales_log.address_line2).to eq("")
expect(sales_log.town_or_city).to eq("Town")
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AA")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E09000033")
end
end
context "with changing the postcode" do
before do
fill_in("sales_log[town_or_city]", with: "Town")
fill_in("sales_log[postcode_full]", with: "AA12AA")
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq("uprn_not_listed")
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 2AA")
expect(sales_log.address_line1).to eq("Address line 1")
expect(sales_log.address_line2).to eq("")
expect(sales_log.town_or_city).to eq("Town")
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AA")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E08000010")
end
end
end
end
context "and the user selects 'address_not_listed' when partial postcode is given" do
before do
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "1AA")
click_button("Search")
choose "The address is not listed, I want to enter the address manually"
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(0) # no
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq("uprn_not_listed")
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq("Address line 1")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("1AA")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq(nil)
end
end
context "and the user selects 'address_not_listed' and then changes their mind and selects an address" do
before do
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
choose "The address is not listed, I want to enter the address manually"
click_button("Save and continue")
visit("/sales-logs/#{sales_log.id}/uprn-selection")
choose("sales-log-uprn-selection-111-field", allow_label_click: true)
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(1)
expect(sales_log.uprn).to eq("111")
expect(sales_log.uprn_confirmed).to eq(1)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 1AA")
expect(sales_log.address_line1).to eq("Some Place")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq("Bristol")
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AA")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E09000033")
end
end
context "and possible addresses found and selected" do
before do
fill_in("sales_log[address_line1_input]", with: "Address line 1")
fill_in("sales_log[postcode_full_input]", with: "AA1 1AA")
click_button("Search")
choose("sales-log-uprn-selection-111-field", allow_label_click: true)
click_button("Save and continue")
end
it "sets correct address fields" do
sales_log.reload
expect(sales_log.uprn_known).to eq(1)
expect(sales_log.uprn).to eq("111")
expect(sales_log.uprn_confirmed).to eq(1)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("AA1 1AA")
expect(sales_log.address_line1).to eq("Some Place")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq("Bristol")
expect(sales_log.address_line1_input).to eq("Address line 1")
expect(sales_log.postcode_full_input).to eq("AA1 1AA")
expect(sales_log.address_search_value_check).to eq(nil)
expect(sales_log.la).to eq("E09000033")
end
end
end
end
end
context "when a log becomes a duplicate" do

2
spec/fixtures/files/sales_logs_csv_export_codes_24.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/sales_logs_csv_export_labels_24.csv vendored

File diff suppressed because one or more lines are too long

2
spec/fixtures/files/sales_logs_csv_export_non_support_labels_24.csv vendored

File diff suppressed because one or more lines are too long

4
spec/models/bulk_upload_spec.rb

@ -24,7 +24,7 @@ RSpec.describe BulkUpload, type: :model do
let(:log) { build(:lettings_log, startdate: Time.zone.local(2025, 4, 2), bulk_upload:) }
it "has the correct number of value checks to be set as confirmed" do
expect(bulk_upload.fields_to_confirm(log)).to match_array %w[rent_value_check void_date_value_check major_repairs_date_value_check pregnancy_value_check retirement_value_check referral_value_check net_income_value_check scharge_value_check pscharge_value_check supcharg_value_check multiple_partners_value_check partner_under_16_value_check reasonother_value_check]
expect(bulk_upload.fields_to_confirm(log)).to match_array %w[rent_value_check void_date_value_check major_repairs_date_value_check pregnancy_value_check retirement_value_check referral_value_check net_income_value_check scharge_value_check pscharge_value_check supcharg_value_check address_search_value_check multiple_partners_value_check partner_under_16_value_check reasonother_value_check]
end
end
@ -32,7 +32,7 @@ RSpec.describe BulkUpload, type: :model do
let(:log) { build(:sales_log, :saledate_today, bulk_upload:) }
it "has the correct number of value checks to be set as confirmed" do
expect(bulk_upload.fields_to_confirm(log)).to match_array %w[value_value_check monthly_charges_value_check percentage_discount_value_check income1_value_check income2_value_check combined_income_value_check retirement_value_check old_persons_shared_ownership_value_check buyer_livein_value_check student_not_child_value_check wheel_value_check mortgage_value_check savings_value_check deposit_value_check staircase_bought_value_check stairowned_value_check hodate_check shared_ownership_deposit_value_check extrabor_value_check grant_value_check discounted_sale_value_check deposit_and_mortgage_value_check multiple_partners_value_check partner_under_16_value_check]
expect(bulk_upload.fields_to_confirm(log)).to match_array %w[value_value_check monthly_charges_value_check percentage_discount_value_check income1_value_check income2_value_check combined_income_value_check retirement_value_check old_persons_shared_ownership_value_check buyer_livein_value_check student_not_child_value_check wheel_value_check mortgage_value_check savings_value_check deposit_value_check staircase_bought_value_check stairowned_value_check hodate_check shared_ownership_deposit_value_check extrabor_value_check grant_value_check discounted_sale_value_check deposit_and_mortgage_value_check address_search_value_check multiple_partners_value_check partner_under_16_value_check]
end
end
end

9
spec/models/form/lettings/pages/address_fallback_spec.rb

@ -24,6 +24,13 @@ RSpec.describe Form::Lettings::Pages::AddressFallback, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "manual_address_entry_selected" => true, "is_supported_housing?" => false }])
expect(page.depends_on).to eq([
{ "is_supported_housing?" => false, "uprn_known" => nil, "uprn_selection" => "uprn_not_listed" },
{ "is_supported_housing?" => false, "uprn_known" => 0, "uprn_selection" => "uprn_not_listed" },
{ "is_supported_housing?" => false, "uprn_confirmed" => 0, "uprn_selection" => "uprn_not_listed" },
{ "is_supported_housing?" => false, "uprn_known" => nil, "address_options_present?" => false },
{ "is_supported_housing?" => false, "uprn_known" => 0, "address_options_present?" => false },
{ "is_supported_housing?" => false, "uprn_confirmed" => 0, "address_options_present?" => false },
])
end
end

42
spec/models/form/lettings/pages/address_search_spec.rb

@ -1,42 +0,0 @@
require "rails_helper"
RSpec.describe Form::Lettings::Pages::AddressSearch, 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, form: instance_double(Form, start_date:)) }
let(:start_date) { Time.utc(2024, 4, 1) }
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[uprn])
end
it "has the correct id" do
expect(page.id).to eq("address_search")
end
it "has the correct description" do
expect(page.description).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "is_supported_housing?" => false, "manual_address_entry_selected" => false }])
end
it "has the correct question number" do
expect(page.question_number).to eq(12)
end
context "with 2025/26 form" do
let(:start_date) { Time.utc(2025, 4, 1) }
it "has the correct question number" do
expect(page.question_number).to eq(16)
end
end
end

68
spec/models/form/lettings/questions/address_search_spec.rb

@ -1,68 +0,0 @@
require "rails_helper"
RSpec.describe Form::Lettings::Questions::AddressSearch, 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, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date:))) }
let(:start_date) { Time.utc(2024, 4, 1) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("uprn")
end
it "has the correct type" do
expect(question.type).to eq("address_search")
end
it "has the correct question number" do
expect(question.question_number).to eq(12)
end
context "with 2025/26 form" do
let(:start_date) { Time.utc(2025, 4, 1) }
it "has the correct question number" do
expect(question.question_number).to eq(16)
end
end
describe "get_extra_check_answer_value" do
context "when address is not present" do
let(:log) { build(:lettings_log, manual_address_entry_selected: false) }
it "returns nil" do
expect(question.get_extra_check_answer_value(log)).to be_nil
end
end
context "when address search is present" do
let(:log) do
build(
:lettings_log,
:completed,
address_line1: "19, Charlton Gardens",
town_or_city: "Bristol",
postcode_full: "BS10 6LU",
la: "E06000023",
uprn_known: 1,
uprn: 107,
uprn_confirmed: 1,
)
end
context "when uprn known" do
it "returns formatted value" do
expect(question.get_extra_check_answer_value(log)).to eq(
"\n\n19, Charlton Gardens\nBristol\nBS10 6LU\nBristol, City of",
)
end
end
end
end
end

8
spec/models/form/lettings/questions/uprn_selection_spec.rb

@ -90,10 +90,9 @@ RSpec.describe Form::Lettings::Questions::UprnSelection, type: :model do
context "when the log has address line 1 input only" do
before do
allow(address_client_instance).to receive(:result).and_return(nil)
log.address_line1_input = "Address line 1"
log.postcode_full_input = nil
log.save!(validate: false)
log.save!(valudate: false)
end
it "has the correct input_playback" do
@ -103,10 +102,9 @@ RSpec.describe Form::Lettings::Questions::UprnSelection, type: :model do
context "when the log has postcode input only" do
before do
allow(address_client_instance).to receive(:result).and_return(nil)
log.address_line1_input = nil
log.postcode_full_input = "A1 1AA"
log.save!(validate: false)
log.save!(valudate: false)
end
it "has the correct input_playback" do
@ -118,7 +116,7 @@ RSpec.describe Form::Lettings::Questions::UprnSelection, type: :model do
before do
log.address_line1_input = "Address line 1"
log.postcode_full_input = "A1 1AA"
log.save!(validate: false)
log.save!(valudate: false)
end
it "has the correct input_playback" do

4
spec/models/form/lettings/questions/uprn_spec.rb

@ -52,14 +52,12 @@ RSpec.describe Form::Lettings::Questions::Uprn, type: :model do
la: "E09000003",
uprn_known:,
uprn:,
manual_address_entry_selected:,
)
end
context "when uprn known nil" do
let(:uprn_known) { nil }
let(:uprn) { nil }
let(:manual_address_entry_selected) { true }
it "returns formatted value" do
expect(question.get_extra_check_answer_value(log)).to be_nil
@ -69,7 +67,6 @@ RSpec.describe Form::Lettings::Questions::Uprn, type: :model do
context "when uprn known" do
let(:uprn_known) { 1 }
let(:uprn) { 1 }
let(:manual_address_entry_selected) { false }
it "returns formatted value" do
expect(question.get_extra_check_answer_value(log)).to eq(
@ -81,7 +78,6 @@ RSpec.describe Form::Lettings::Questions::Uprn, type: :model do
context "when uprn not known" do
let(:uprn_known) { 0 }
let(:uprn) { nil }
let(:manual_address_entry_selected) { true }
it "returns formatted value" do
expect(question.get_extra_check_answer_value(log)).to be_nil

12
spec/models/form/lettings/subsections/property_information_spec.rb

@ -64,7 +64,11 @@ RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do
it "has correct pages" do
expect(property_information.pages.map(&:id)).to eq(
%w[
address_search
uprn
uprn_confirmation
address_matcher
no_address_found
uprn_selection
address
property_local_authority
local_authority_rent_value_check
@ -97,7 +101,11 @@ RSpec.describe Form::Lettings::Subsections::PropertyInformation, type: :model do
it "has correct pages" do
expect(property_information.pages.map(&:id)).to eq(
%w[
address_search
uprn
uprn_confirmation
address_matcher
no_address_found
uprn_selection
address
property_local_authority
local_authority_rent_value_check

9
spec/models/form/sales/pages/address_fallback_spec.rb

@ -24,6 +24,13 @@ RSpec.describe Form::Sales::Pages::AddressFallback, type: :model do
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "manual_address_entry_selected" => true }])
expect(page.depends_on).to eq([
{ "uprn_known" => nil, "uprn_selection" => "uprn_not_listed" },
{ "uprn_known" => 0, "uprn_selection" => "uprn_not_listed" },
{ "uprn_confirmed" => 0, "uprn_selection" => "uprn_not_listed" },
{ "uprn_known" => nil, "address_options_present?" => false },
{ "uprn_known" => 0, "address_options_present?" => false },
{ "uprn_confirmed" => 0, "address_options_present?" => false },
])
end
end

42
spec/models/form/sales/pages/address_search_spec.rb

@ -1,42 +0,0 @@
require "rails_helper"
RSpec.describe Form::Sales::Pages::AddressSearch, 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, form: instance_double(Form, start_date:)) }
let(:start_date) { Time.utc(2024, 4, 1) }
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[uprn])
end
it "has the correct id" do
expect(page.id).to eq("address_search")
end
it "has the correct description" do
expect(page.description).to be_nil
end
it "has correct depends_on" do
expect(page.depends_on).to eq([{ "manual_address_entry_selected" => false }])
end
it "has the correct question number" do
expect(page.question_number).to eq(15)
end
context "with 2025/26 form" do
let(:start_date) { Time.utc(2025, 4, 1) }
it "has the correct question number" do
expect(page.question_number).to eq(13)
end
end
end

4
spec/models/form/sales/pages/uprn_confirmation_spec.rb

@ -7,10 +7,6 @@ RSpec.describe Form::Sales::Pages::UprnConfirmation, type: :model do
let(:page_definition) { nil }
let(:subsection) { instance_double(Form::Subsection) }
before do
allow(subsection).to receive(:form).and_return(instance_double(Form, start_year_2024_or_later?: false))
end
it "has correct subsection" do
expect(page.subsection).to eq(subsection)
end

68
spec/models/form/sales/questions/address_search_spec.rb

@ -1,68 +0,0 @@
require "rails_helper"
RSpec.describe Form::Sales::Questions::AddressSearch, 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, subsection: instance_double(Form::Subsection, form: instance_double(Form, start_date:))) }
let(:start_date) { Time.utc(2024, 4, 1) }
it "has correct page" do
expect(question.page).to eq(page)
end
it "has the correct id" do
expect(question.id).to eq("uprn")
end
it "has the correct type" do
expect(question.type).to eq("address_search")
end
it "has the correct question number" do
expect(question.question_number).to eq(15)
end
context "with 2025/26 form" do
let(:start_date) { Time.utc(2025, 4, 1) }
it "has the correct question number" do
expect(question.question_number).to eq(13)
end
end
describe "get_extra_check_answer_value" do
context "when address is not present" do
let(:log) { build(:sales_log, manual_address_entry_selected: false) }
it "returns nil" do
expect(question.get_extra_check_answer_value(log)).to be_nil
end
end
context "when address search is present" do
let(:log) do
build(
:sales_log,
:completed,
address_line1: "19, Charlton Gardens",
town_or_city: "Bristol",
postcode_full: "BS10 6LU",
la: "E06000023",
uprn_known: 1,
uprn: 107,
uprn_confirmed: 1,
)
end
context "when uprn known" do
it "returns formatted value" do
expect(question.get_extra_check_answer_value(log)).to eq(
"\n\n19, Charlton Gardens\nBristol\nBS10 6LU\nBristol, City of",
)
end
end
end
end
end

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

@ -90,10 +90,9 @@ RSpec.describe Form::Sales::Questions::UprnSelection, type: :model do
context "when the log has address line 1 input only" do
before do
allow(address_client_instance).to receive(:result).and_return(nil)
log.address_line1_input = "Address line 1"
log.postcode_full_input = nil
log.save!(validate: false)
log.save!(valudate: false)
end
it "has the correct input_playback" do
@ -103,10 +102,9 @@ RSpec.describe Form::Sales::Questions::UprnSelection, type: :model do
context "when the log has postcode input only" do
before do
allow(address_client_instance).to receive(:result).and_return(nil)
log.address_line1_input = nil
log.postcode_full_input = "A1 1AA"
log.save!(validate: false)
log.save!(valudate: false)
end
it "has the correct input_playback" do
@ -118,7 +116,7 @@ RSpec.describe Form::Sales::Questions::UprnSelection, type: :model do
before do
log.address_line1_input = "Address line 1"
log.postcode_full_input = "A1 1AA"
log.save!(validate: false)
log.save!(valudate: false)
end
it "has the correct input_playback" do

12
spec/models/form/sales/subsections/property_information_spec.rb

@ -55,7 +55,11 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do
it "has correct pages" do
expect(property_information.pages.map(&:id)).to eq(
%w[
address_search
uprn
uprn_confirmation
address_matcher
no_address_found
uprn_selection
address
property_local_authority
local_authority_buyer_1_income_max_value_check
@ -85,7 +89,11 @@ RSpec.describe Form::Sales::Subsections::PropertyInformation, type: :model do
it "has correct pages" do
expect(property_information.pages.map(&:id)).to eq(
%w[
address_search
uprn
uprn_confirmation
address_matcher
no_address_found
uprn_selection
address
property_local_authority
local_authority_buyer_1_income_max_value_check

7
spec/models/sales_log_spec.rb

@ -566,7 +566,6 @@ RSpec.describe SalesLog, type: :model do
ppostcode_full: nil,
prevloc: nil,
saledate: Time.zone.local(2024, 5, 2),
manual_address_entry_selected: true,
})
end
@ -618,7 +617,7 @@ RSpec.describe SalesLog, type: :model do
end
let(:address_sales_log_25_26) do
create(:sales_log, :shared_ownership_setup_complete, postcode_full: "CA10 1AA", saledate: Time.zone.local(2025, 5, 2), manual_address_entry_selected: true)
create(:sales_log, :shared_ownership_setup_complete, postcode_full: "CA10 1AA", saledate: Time.zone.local(2025, 5, 2))
end
before do
@ -673,11 +672,11 @@ RSpec.describe SalesLog, type: :model do
context "when saving address with LAs that have changed E-codes" do
context "when address inferred from uprn - we still get LA from postcode" do
let(:address_sales_log_24_25) do
create(:sales_log, :shared_ownership_setup_complete, manual_address_entry_selected: false, uprn_known: 1, uprn: 1, saledate: Time.zone.local(2024, 5, 2))
create(:sales_log, :shared_ownership_setup_complete, uprn_known: 1, uprn: 1, saledate: Time.zone.local(2024, 5, 2))
end
let(:address_sales_log_25_26) do
create(:sales_log, :shared_ownership_setup_complete, manual_address_entry_selected: false, uprn_known: 1, uprn: 1, saledate: Time.zone.local(2025, 5, 2))
create(:sales_log, :shared_ownership_setup_complete, uprn_known: 1, uprn: 1, saledate: Time.zone.local(2025, 5, 2))
end
before do

4
spec/models/validations/sales/property_validations_spec.rb

@ -136,9 +136,9 @@ RSpec.describe Validations::Sales::PropertyValidations do
context "when within the limit and only numeric" do
let(:record) { build(:sales_log, uprn: "123456789012") }
it "does not add an invalid UPRN error" do
it "does not add an error" do
property_validator.validate_uprn(record)
expect(record.errors.added?(:uprn, I18n.t("validations.sales.property_information.uprn.invalid"))).to be false
expect(record.errors).not_to be_present
end
end
end

2
spec/request_helper.rb

@ -20,7 +20,7 @@ module RequestHelper
body = { results: [{ DPA: { UPRN: "10033558653" } }] }.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/find?key&maxresults=10&minmatch=0.4&query=Address%20line%201,%20SW1A%201AA")
.to_return(status: 200, body:, headers: {})
body = { results: [{ DPA: { "POSTCODE": "SW1A 1AA", "POST_TOWN": "London", "PO_BOX_NUMBER": "The Mall, City Of Westminster" } }] }.to_json
body = { results: [{ DPA: { "POSTCODE": "SW1A 1AA", "POST_TOWN": "London" } }] }.to_json
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key&uprn=1")
.to_return(status: 200, body:, headers: {})
WebMock.stub_request(:get, "https://api.os.uk/search/places/v1/uprn?dataset=DPA,LPI&key&uprn=10033558653")

148
spec/requests/address_search_controller_spec.rb

@ -1,148 +0,0 @@
require "rails_helper"
RSpec.describe AddressSearchController, type: :request do
let(:user) { create(:user) }
before do
sign_in user
end
describe "#manual input" do
context "when no address data is given and user chooses to enter address manually" do
let(:sales_log) { create(:sales_log, :shared_ownership_setup_complete, manual_address_entry_selected: false, assigned_to: user) }
it "correctly sets address fields" do
sales_log.reload
expect(sales_log.manual_address_entry_selected).to eq(false)
expect(sales_log.uprn_known).to eq(nil)
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.la).to eq(nil)
get "/address-search/manual-input/sales_log/#{sales_log.id}"
sales_log.reload
expect(sales_log.manual_address_entry_selected).to eq(true)
expect(sales_log.uprn_known).to eq(0)
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.la).to eq(nil)
end
end
context "when choosing to manually input an address for a log that has an address searched value" do
let(:lettings_log) { create(:lettings_log, :completed, manual_address_entry_selected: false, assigned_to: user) }
it "correctly sets address fields" do
lettings_log.reload
expect(lettings_log.uprn_known).to eq(1)
expect(lettings_log.uprn).to eq("10033558653")
expect(lettings_log.uprn_confirmed).to eq(1)
expect(lettings_log.uprn_selection).to eq("10033558653")
expect(lettings_log.postcode_known).to eq(1)
expect(lettings_log.postcode_full).to eq("SW1A 1AA")
expect(lettings_log.address_line1).to eq("The Mall, City Of Westminster")
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq("London")
expect(lettings_log.la).to eq("E09000033")
get "/address-search/manual-input/lettings_log/#{lettings_log.id}"
lettings_log.reload
expect(lettings_log.manual_address_entry_selected).to eq(true)
expect(lettings_log.uprn_known).to eq(0)
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.la).to eq(nil)
end
end
end
describe "#search input" do
context "when no address is entered manually and choosing to search instead" do
let(:lettings_log) { create(:lettings_log, :setup_completed, manual_address_entry_selected: true, assigned_to: user) }
it "correctly sets address fields" do
lettings_log.reload
expect(lettings_log.manual_address_entry_selected).to eq(true)
expect(lettings_log.uprn_known).to eq(0)
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.la).to eq(nil)
get "/address-search/search-input/lettings_log/#{lettings_log.id}"
lettings_log.reload
expect(lettings_log.manual_address_entry_selected).to eq(false)
expect(lettings_log.uprn_known).to eq(nil)
expect(lettings_log.uprn).to eq(nil)
expect(lettings_log.uprn_confirmed).to eq(nil)
expect(lettings_log.uprn_selection).to eq(nil)
expect(lettings_log.postcode_known).to eq(nil)
expect(lettings_log.postcode_full).to eq(nil)
expect(lettings_log.address_line1).to eq(nil)
expect(lettings_log.address_line2).to eq(nil)
expect(lettings_log.town_or_city).to eq(nil)
expect(lettings_log.la).to eq(nil)
end
end
context "when choosing to search for an address for a log that has an address searched value" do
let(:sales_log) { create(:sales_log, :completed, manual_address_entry_selected: true, town_or_city: "Test Town", assigned_to: user) }
it "correctly sets address fields" do
sales_log.reload
expect(sales_log.manual_address_entry_selected).to eq(true)
expect(sales_log.uprn_known).to eq(0)
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(0)
expect(sales_log.postcode_full).to eq("SW1A 1AA")
expect(sales_log.address_line1).to eq("Address line 1")
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq("Test Town")
expect(sales_log.la).to eq("E09000033")
get "/address-search/search-input/sales_log/#{sales_log.id}"
sales_log.reload
expect(sales_log.manual_address_entry_selected).to eq(false)
expect(sales_log.uprn_known).to eq(nil)
expect(sales_log.uprn).to eq(nil)
expect(sales_log.uprn_confirmed).to eq(nil)
expect(sales_log.uprn_selection).to eq(nil)
expect(sales_log.pcodenk).to eq(nil)
expect(sales_log.postcode_full).to eq(nil)
expect(sales_log.address_line1).to eq(nil)
expect(sales_log.address_line2).to eq(nil)
expect(sales_log.town_or_city).to eq(nil)
expect(sales_log.la).to eq(nil)
end
end
end
end

10
spec/requests/duplicate_logs_controller_spec.rb

@ -77,8 +77,8 @@ RSpec.describe DuplicateLogsController, type: :request do
end
it "displays check your answers for each log with correct questions where UPRN is given" do
lettings_log.update!(uprn: "123", uprn_known: 1, uprn_confirmed: 1, manual_address_entry_selected: false)
duplicate_logs[0].update!(uprn: "123", uprn_known: 1, uprn_confirmed: 1, manual_address_entry_selected: false)
lettings_log.update!(uprn: "123", uprn_known: 1, uprn_confirmed: 1)
duplicate_logs[0].update!(uprn: "123", uprn_known: 1, uprn_confirmed: 1)
get "/lettings-logs/#{lettings_log.id}/duplicate-logs?original_log_id=#{lettings_log.id}"
expect(page).to have_content("Q5 - Tenancy start date", count: 3)
@ -186,9 +186,9 @@ RSpec.describe DuplicateLogsController, type: :request do
end
it "displays check your answers for each log with correct questions when UPRN is given" do
sales_log.update!(uprn: "123", uprn_known: 1, manual_address_entry_selected: false)
duplicate_logs[0].update!(uprn: "123", uprn_known: 1, manual_address_entry_selected: false)
duplicate_logs[1].update!(uprn: "123", uprn_known: 1, manual_address_entry_selected: false)
sales_log.update!(uprn: "123", uprn_known: 1)
duplicate_logs[0].update!(uprn: "123", uprn_known: 1)
duplicate_logs[1].update!(uprn: "123", uprn_known: 1)
get "/sales-logs/#{sales_log.id}/duplicate-logs?original_log_id=#{sales_log.id}"
expect(page).to have_content("Q1 - Sale completion date", count: 3)

8
spec/services/csv/sales_log_csv_service_spec.rb

@ -199,7 +199,7 @@ RSpec.describe Csv::SalesLogCsvService do
let(:fixed_time) { Time.zone.local(2024, 5, 1) }
before do
log.update!(nationality_all: 36, manual_address_entry_selected: false, uprn: "1", uprn_known: 1)
log.update!(nationality_all: 36)
end
it "exports the CSV with the 2024 ordering and all values correct" do
@ -286,10 +286,6 @@ RSpec.describe Csv::SalesLogCsvService do
let(:fixed_time) { Time.zone.local(2024, 5, 1) }
let(:year) { 2024 }
before do
log.update!(manual_address_entry_selected: false, uprn: "1", uprn_known: 1)
end
it "exports the CSV with all values correct" do
expected_content = CSV.read("spec/fixtures/files/sales_logs_csv_export_codes_24.csv")
values_to_delete = %w[ID]
@ -342,7 +338,7 @@ RSpec.describe Csv::SalesLogCsvService do
let(:fixed_time) { Time.zone.local(2024, 5, 1) }
before do
log.update!(nationality_all: 36, manual_address_entry_selected: false, uprn: "1", uprn_known: 1)
log.update!(nationality_all: 36)
end
context "and exporting with labels" do

2
spec/services/exports/lettings_log_export_service_spec.rb

@ -431,7 +431,7 @@ RSpec.describe Exports::LettingsLogExportService do
end
context "and one lettings log is available for export" do
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered", manual_address_entry_selected: false, uprn: "1", uprn_known: 1) }
let!(:lettings_log) { FactoryBot.create(:lettings_log, :completed, assigned_to: user, age1: 35, sex1: "F", age2: 32, sex2: "M", ppostcode_full: "A1 1AA", nationality_all_group: 13, propcode: "123", postcode_full: "SE2 6RT", tenancycode: "BZ737", startdate: Time.zone.local(2024, 4, 2, 10, 36, 49), voiddate: Time.zone.local(2021, 11, 3), mrcdate: Time.zone.local(2022, 5, 5, 10, 36, 49), tenancylength: 5, underoccupation_benefitcap: 4, creation_method: 2, bulk_upload_id: 1, address_line1_as_entered: "address line 1 as entered", address_line2_as_entered: "address line 2 as entered", town_or_city_as_entered: "town or city as entered", county_as_entered: "county as entered", postcode_full_as_entered: "AB1 2CD", la_as_entered: "la as entered") }
let(:expected_zip_filename) { "core_2024_2025_apr_mar_f0001_inc0001.zip" }
let(:expected_data_filename) { "core_2024_2025_apr_mar_f0001_inc0001_pt001.xml" }
let(:xml_export_file) { File.open("spec/fixtures/exports/general_needs_log_24_25.xml", "r:UTF-8") }

5
spec/shared/shared_examples_for_derived_fields.rb

@ -25,14 +25,11 @@ RSpec.shared_examples "shared examples for derived fields" do |log_type|
end
it "does not affect older logs with uprn_confirmed == 0" do
Timecop.freeze(Time.zone.local(2023, 4, 1)) do
log = FactoryBot.build(log_type, uprn_known: 0, uprn: nil, uprn_confirmed: 0)
allow(log.form).to receive(:start_year_2024_or_later?).and_return(false)
expect { log.set_derived_fields! }.to not_change(log, :uprn_known)
.and not_change(log, :uprn)
.and not_change(log, :uprn_confirmed)
end
Timecop.return
end
end
end

2
spec/shared/shared_log_examples.rb

@ -81,6 +81,7 @@ RSpec.shared_examples "shared log examples" do |log_type|
expect { log.process_uprn_change! }.to change(log, :address_line1).from(nil).to("0, Building Name, Thoroughfare")
.and change(log, :town_or_city).from(nil).to("Posttown")
.and change(log, :postcode_full).from(nil).to("POSTCODE")
.and change(log, :uprn_confirmed).from(1).to(nil)
.and change(log, :county).from("county").to(nil)
end
end
@ -155,6 +156,7 @@ RSpec.shared_examples "shared log examples" do |log_type|
.and change(log, :uprn_confirmed).from(nil).to(1)
.and change(log, :uprn).from(nil).to("UPRN")
.and change(log, :uprn_known).from(nil).to(1)
.and change(log, :uprn_selection).from("UPRN").to(nil)
.and change(log, :county).from("county").to(nil)
end
end

Loading…
Cancel
Save