Browse Source

Cldc 575 inferred la (#165)

* Infer la from postcode

* Fix other tests and lint

* Add routing based on inferred la

* reset la to inferred false

* Use postcodes io gem

* reset values if la cannot be inferred

* Fix tests
pull/166/head
kosiakkatrina 3 years ago committed by GitHub
parent
commit
d236c5334a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      Gemfile
  2. 12
      Gemfile.lock
  3. 20
      app/models/case_log.rb
  4. 2
      app/models/form/page.rb
  5. 11
      config/forms/2021_2022.json
  6. 7
      db/migrate/20211209092131_add_is_la_inferred.rb
  7. 1
      db/schema.rb
  8. 4
      spec/controllers/admin/case_logs_controller_spec.rb
  9. 4
      spec/controllers/admin/dashboard_controller_spec.rb
  10. 2
      spec/features/form/check_answers_page_spec.rb
  11. 2
      spec/features/form/conditional_questions_spec.rb
  12. 2
      spec/features/form/form_navigation_spec.rb
  13. 27
      spec/features/form/page_routing_spec.rb
  14. 2
      spec/features/form/saving_data_spec.rb
  15. 10
      spec/features/form/validations_spec.rb
  16. 30
      spec/fixtures/forms/test_form.json
  17. 6
      spec/helpers/tasklist_helper_spec.rb
  18. 43
      spec/models/case_log_spec.rb
  19. 2
      spec/models/form_handler_spec.rb
  20. 4
      spec/models/organisation_spec.rb
  21. 4
      spec/models/user_spec.rb
  22. 9
      spec/request_helper.rb
  23. 3
      spec/requests/case_log_controller_spec.rb
  24. 5
      spec/requests/soft_validations_controller_spec.rb
  25. 6
      spec/views/case_log_index_view_spec.rb

2
Gemfile

@ -37,6 +37,7 @@ gem "devise", github: "ghiculescu/devise", branch: "error-code-422"
# UK postcode parsing and validation
gem "uk_postcode"
# Use Ruby objects to build reusable markup. A React inspired evolution of the presenter pattern
gem "postcodes_io"
gem "view_component"
group :development, :test do
@ -66,6 +67,7 @@ group :test do
gem "factory_bot_rails"
gem "selenium-webdriver", require: false
gem "simplecov", require: false
gem "webmock"
%w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib|
gem lib, git: "https://github.com/rspec/#{lib}.git", branch: "main", require: false
end

12
Gemfile.lock

@ -158,6 +158,8 @@ GEM
childprocess (4.1.0)
coderay (1.1.3)
concurrent-ruby (1.1.9)
crack (0.4.5)
rexml
crass (1.0.6)
deep_merge (1.2.1)
diff-lcs (1.4.4)
@ -169,6 +171,7 @@ GEM
dotenv (= 2.7.6)
railties (>= 3.2)
erubi (1.10.0)
excon (0.89.0)
factory_bot (6.2.0)
activesupport (>= 5.0.0)
factory_bot_rails (6.2.0)
@ -192,6 +195,7 @@ GEM
has_scope (0.8.0)
actionpack (>= 5.2)
activesupport (>= 5.2)
hashdiff (1.0.1)
hotwire-rails (0.1.3)
rails (>= 6.0.0)
stimulus-rails
@ -252,6 +256,8 @@ GEM
parser (3.0.3.1)
ast (~> 2.4.1)
pg (1.2.3)
postcodes_io (0.4.0)
excon (~> 0.39)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
@ -389,6 +395,10 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webmock (3.14.0)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webpacker (5.4.3)
activesupport (>= 5.2)
rack-proxy (>= 0.6.1)
@ -425,6 +435,7 @@ DEPENDENCIES
listen (~> 3.3)
overcommit (>= 0.37.0)
pg (~> 1.1)
postcodes_io
pry-byebug
puma (~> 5.0)
rack-mini-profiler (~> 2.0)
@ -445,6 +456,7 @@ DEPENDENCIES
uk_postcode
view_component
web-console (>= 4.1.0)
webmock
webpacker (~> 5.0)
RUBY VERSION

20
app/models/case_log.rb

@ -1,3 +1,5 @@
require "postcodes_io"
class CaseLogValidator < ActiveModel::Validator
# Validations methods need to be called 'validate_' to run on model save
# or form page submission
@ -117,7 +119,7 @@ class CaseLog < ApplicationRecord
enum postcode_known: POLAR, _suffix: true
enum la_known: POLAR, _suffix: true
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at renttype lettype].freeze
AUTOGENERATED_FIELDS = %w[id status created_at updated_at discarded_at renttype lettype is_la_inferred].freeze
OPTIONAL_FIELDS = %w[postcode_known
la_known
first_time_property_let_as_social_housing].freeze
@ -159,6 +161,8 @@ class CaseLog < ApplicationRecord
private
PIO = Postcodes::IO.new
def update_status!
self.status = if all_fields_completed? && errors.empty?
"completed"
@ -193,6 +197,20 @@ private
self.hhmemb = other_hhmemb + 1 if other_hhmemb.present?
self.renttype = RENT_TYPE_MAPPING[rent_type]
self.lettype = "#{renttype} #{needstype} #{owning_organisation['Org type']}" if renttype.present? && needstype.present? && owning_organisation["Org type"].present?
self.is_la_inferred = false if is_la_inferred.nil?
self.la = get_la(property_postcode)
end
def get_la(postcode)
if postcode.present?
postcode_lookup = PIO.lookup(postcode)
if postcode_lookup && postcode_lookup.info.present?
self.is_la_inferred = true
return postcode_lookup.admin_district
end
end
self.la = nil
self.is_la_inferred = false
end
def all_fields_completed?

2
app/models/form/page.rb

@ -24,7 +24,7 @@ class Form::Page
return true unless depends_on
depends_on.all? do |question, value|
case_log[question].present? && case_log[question] == value
!case_log[question].nil? && case_log[question] == value
end
end
end

11
config/forms/2021_2022.json

@ -1119,10 +1119,10 @@
"1": "Yes"
},
"conditional_for": {
"postcode": ["Yes"]
"property_postcode": ["Yes"]
}
},
"postcode": {
"property_postcode": {
"check_answer_label": "Postcode",
"header": "",
"hint_text": "",
@ -1145,7 +1145,8 @@
"1": "Yes"
}
}
}
},
"depends_on": {"is_la_inferred": false}
},
"select_local_authority": {
"header": "",
@ -1473,7 +1474,7 @@
}
}
},
"depends_on": { "la_known": "Yes" }
"depends_on": { "la_known": "Yes", "is_la_inferred": false }
},
"why_dont_you_know_la": {
"header": "",
@ -1486,7 +1487,7 @@
"type": "textarea"
}
},
"depends_on": { "la_known": "No" }
"depends_on": { "la_known": "No", "is_la_inferred": false }
},
"first_time_property_let_as_social_housing": {
"header": "",

7
db/migrate/20211209092131_add_is_la_inferred.rb

@ -0,0 +1,7 @@
class AddIsLaInferred < ActiveRecord::Migration[6.1]
def change
change_table :case_logs, bulk: true do |t|
t.column :is_la_inferred, :boolean
end
end
end

1
db/schema.rb

@ -174,6 +174,7 @@ ActiveRecord::Schema.define(version: 2021_12_13_122642) do
t.integer "day"
t.integer "month"
t.integer "year"
t.boolean "is_la_inferred"
t.index ["discarded_at"], name: "index_case_logs_on_discarded_at"
t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id"
t.index ["owning_organisation_id"], name: "index_case_logs_on_owning_organisation_id"

4
spec/controllers/admin/case_logs_controller_spec.rb

@ -1,7 +1,11 @@
require "rails_helper"
require_relative "../../support/devise"
require_relative "../../request_helper"
describe Admin::CaseLogsController, type: :controller do
before do
RequestHelper.stub_http_requests
end
render_views
let(:page) { Capybara::Node::Simple.new(response.body) }
let(:resource_title) { "Logs" }

4
spec/controllers/admin/dashboard_controller_spec.rb

@ -1,7 +1,11 @@
require "rails_helper"
require_relative "../../support/devise"
require_relative "../../request_helper"
describe Admin::DashboardController, type: :controller do
before do
RequestHelper.stub_http_requests
end
render_views
let(:page) { Capybara::Node::Simple.new(response.body) }
let(:resource_title) { "Dashboard" }

2
spec/features/form/check_answers_page_spec.rb

@ -1,5 +1,6 @@
require "rails_helper"
require_relative "helpers"
require_relative "../../request_helper"
RSpec.describe "Form Check Answers Page" do
include Helpers
@ -22,6 +23,7 @@ RSpec.describe "Form Check Answers Page" do
let(:id) { case_log.id }
before do
RequestHelper.stub_http_requests
sign_in user
end

2
spec/features/form/conditional_questions_spec.rb

@ -1,5 +1,6 @@
require "rails_helper"
require_relative "helpers"
require_relative "../../request_helper"
RSpec.describe "Form Conditional Questions" do
include Helpers
@ -15,6 +16,7 @@ RSpec.describe "Form Conditional Questions" do
let(:id) { case_log.id }
before do
RequestHelper.stub_http_requests
sign_in user
end

2
spec/features/form/form_navigation_spec.rb

@ -1,5 +1,6 @@
require "rails_helper"
require_relative "helpers"
require_relative "../../request_helper"
RSpec.describe "Form Navigation" do
include Helpers
@ -23,6 +24,7 @@ RSpec.describe "Form Navigation" do
end
before do
RequestHelper.stub_http_requests
sign_in user
end

27
spec/features/form/page_routing_spec.rb

@ -1,5 +1,6 @@
require "rails_helper"
require_relative "helpers"
require_relative "../../request_helper"
RSpec.describe "Form Page Routing" do
include Helpers
@ -15,6 +16,7 @@ RSpec.describe "Form Page Routing" do
let(:id) { case_log.id }
before do
RequestHelper.stub_http_requests
allow_any_instance_of(CaseLogValidator).to receive(:validate_pregnancy).and_return(true)
sign_in user
end
@ -45,4 +47,29 @@ RSpec.describe "Form Page Routing" do
click_button("Save and continue")
expect(page).to have_current_path("/logs/#{id}/conditional-question/check-answers")
end
context "inferred answers routing", js: true do
it "shows question if the answer could not be inferred" do
visit("/logs/#{id}/property-postcode")
fill_in("case-log-property-postcode-field", with: "P0 5ST")
click_button("Save and continue")
expect(page).to have_current_path("/logs/#{id}/do-you-know-the-local-authority")
end
it "shows question if the answer could not be inferred" do
visit("/logs/#{id}/property-postcode")
click_button("Save and continue")
expect(page).to have_current_path("/logs/#{id}/do-you-know-the-local-authority")
end
it "does not show question if the answer could be inferred" do
stub_request(:get, /api.postcodes.io/)
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\"}}", headers: {})
visit("/logs/#{id}/property-postcode")
fill_in("case-log-property-postcode-field", with: "P0 5ST")
click_button("Save and continue")
expect(page).to have_current_path("/logs/#{id}/property-wheelchair-accessible")
end
end
end

2
spec/features/form/saving_data_spec.rb

@ -1,5 +1,6 @@
require "rails_helper"
require_relative "helpers"
require_relative "../../request_helper"
RSpec.describe "Form Saving Data" do
include Helpers
@ -31,6 +32,7 @@ RSpec.describe "Form Saving Data" do
end
before do
RequestHelper.stub_http_requests
sign_in user
end

10
spec/features/form/validations_spec.rb

@ -1,7 +1,13 @@
require "rails_helper"
require_relative "helpers"
require_relative "../../request_helper"
RSpec.describe "validations" do
before do
RequestHelper.stub_http_requests
sign_in user
end
include Helpers
let(:user) { FactoryBot.create(:user) }
let(:case_log) do
@ -21,10 +27,6 @@ RSpec.describe "validations" do
end
let(:id) { case_log.id }
before do
sign_in user
end
describe "Question validation" do
context "given an invalid tenant age" do
it " of less than 0 it shows validation" do

30
spec/fixtures/forms/test_form.json vendored

@ -224,6 +224,36 @@
"property_information": {
"label": "Property information",
"pages": {
"property_postcode": {
"header": "",
"description": "",
"questions": {
"property_postcode": {
"check_answer_label": "Postcode",
"header": "",
"hint_text": "",
"type": "text",
"width": 5
}
}
},
"do_you_know_the_local_authority": {
"header": "",
"description": "",
"questions": {
"la_known": {
"check_answer_label": "Do you know what local authority the property is located in?",
"header": "Do you know what local authority the property is located in?",
"hint_text": "",
"type": "radio",
"answer_options": {
"0": "No",
"1": "Yes"
}
}
},
"depends_on": {"is_la_inferred": false}
},
"property_wheelchair_accessible": {
"questions": {
"wchair": {

6
spec/helpers/tasklist_helper_spec.rb

@ -1,6 +1,10 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe TasklistHelper do
before do
RequestHelper.stub_http_requests
end
let(:empty_case_log) { FactoryBot.create(:case_log) }
let(:case_log) { FactoryBot.create(:case_log, :in_progress) }
form_handler = FormHandler.instance
@ -31,7 +35,7 @@ RSpec.describe TasklistHelper do
end
it "returns the number of sections in progress" do
expect(get_subsections_count(form, case_log, :in_progress)).to eq(2)
expect(get_subsections_count(form, case_log, :in_progress)).to eq(3)
end
it "returns 0 for invalid state" do

43
spec/models/case_log_spec.rb

@ -1,8 +1,12 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe Form, type: :model do
let(:owning_organisation) { FactoryBot.create(:organisation) }
let(:managing_organisation) { owning_organisation }
before do
RequestHelper.stub_http_requests
end
describe "#new" do
it "validates age is a number" do
@ -1016,5 +1020,44 @@ RSpec.describe Form, type: :model do
expect(record_from_db["month"]).to eq(10)
expect(record_from_db["year"]).to eq(2021)
end
context "addresses" do
before do
stub_request(:get, /api.postcodes.io/)
.to_return(status: 200, body: "{\"status\":200,\"result\":{\"admin_district\":\"Manchester\"}}", headers: {})
end
let!(:address_case_log) do
CaseLog.create({
managing_organisation: organisation,
owning_organisation: organisation,
property_postcode: "M1 1AE",
})
end
it "correctly infers la" do
address_case_log.reload
record_from_db = ActiveRecord::Base.connection.execute("select la from case_logs where id=#{address_case_log.id}").to_a[0]
expect(address_case_log.la).to eq("Manchester")
expect(record_from_db["la"]).to eq("E08000003")
end
it "correctly resets all fields" do
address_case_log.reload
record_from_db = ActiveRecord::Base.connection.execute("select la from case_logs where id=#{address_case_log.id}").to_a[0]
expect(address_case_log.la).to eq("Manchester")
expect(record_from_db["la"]).to eq("E08000003")
address_case_log.update!({ property_postcode: "" })
address_case_log.reload
record_from_db = ActiveRecord::Base.connection.execute("select la, property_postcode from case_logs where id=#{address_case_log.id}").to_a[0]
expect(record_from_db["property_postcode"]).to eq("")
expect(address_case_log.la).to eq(nil)
expect(record_from_db["la"]).to eq(nil)
end
end
end
end

2
spec/models/form_handler_spec.rb

@ -15,7 +15,7 @@ RSpec.describe FormHandler do
form_handler = FormHandler.instance
form = form_handler.get_form("test_form")
expect(form).to be_a(Form)
expect(form.pages.count).to eq(25)
expect(form.pages.count).to eq(27)
end
end

4
spec/models/organisation_spec.rb

@ -1,6 +1,10 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe Organisation, type: :model do
before do
RequestHelper.stub_http_requests
end
describe "#new" do
let(:user) { FactoryBot.create(:user) }
let(:organisation) { user.organisation }

4
spec/models/user_spec.rb

@ -1,6 +1,10 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe User, type: :model do
before do
RequestHelper.stub_http_requests
end
describe "#new" do
let(:user) { FactoryBot.create(:user) }
let(:other_organisation) { FactoryBot.create(:organisation) }

9
spec/request_helper.rb

@ -0,0 +1,9 @@
require "webmock/rspec"
module RequestHelper
def self.stub_http_requests
WebMock.disable_net_connect!(allow_localhost: true)
WebMock.stub_request(:get, /api.postcodes.io/)
.to_return(status: 200, body: "{\"status\":404,\"error\":\"Postcode not found\"}", headers: {})
end
end

3
spec/requests/case_log_controller_spec.rb

@ -1,4 +1,5 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe CaseLogsController, type: :request do
let(:owning_organisation) { FactoryBot.create(:organisation) }
@ -19,6 +20,7 @@ RSpec.describe CaseLogsController, type: :request do
end
before do
RequestHelper.stub_http_requests
allow(ENV).to receive(:[])
allow(ENV).to receive(:[]).with("API_USER").and_return(api_username)
allow(ENV).to receive(:[]).with("API_KEY").and_return(api_password)
@ -136,6 +138,7 @@ RSpec.describe CaseLogsController, type: :request do
let(:headers) { { "Accept" => "text/html" } }
before do
RequestHelper.stub_http_requests
sign_in user
get "/logs", headers: headers, params: {}
end

5
spec/requests/soft_validations_controller_spec.rb

@ -1,10 +1,15 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe SoftValidationsController, type: :request do
let(:params) { { case_log_id: case_log.id } }
let(:url) { "/logs/#{case_log.id}/net-income/soft-validations" }
let(:user) { FactoryBot.create(:user) }
before do
RequestHelper.stub_http_requests
end
context "a not signed in user" do
let(:case_log) { FactoryBot.create(:case_log, :in_progress) }

6
spec/views/case_log_index_view_spec.rb

@ -1,5 +1,11 @@
require "rails_helper"
require_relative "../request_helper"
RSpec.describe "case_logs/index" do
before do
RequestHelper.stub_http_requests
end
let(:in_progress_log) { FactoryBot.create(:case_log, :in_progress) }
let(:completed_log) { FactoryBot.create(:case_log, :completed) }

Loading…
Cancel
Save