Browse Source

CLDC-456-start-date-validations (#683)

* start date validations

* remove condition

* move code

* lint fixes

* updates

* content update

* remove unneeded validations

* validations

* review changes

* Update app/models/validations/date_validations.rb

Co-authored-by: baarkerlounger  <5101747+baarkerlounger@users.noreply.github.com>

* update error messages

* lint fixes

* fix specs

Co-authored-by: baarkerlounger  <5101747+baarkerlounger@users.noreply.github.com>
pull/647/head
Dushan 3 years ago committed by GitHub
parent
commit
d338d277bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      app/models/case_log.rb
  2. 1
      app/models/scheme.rb
  3. 11
      app/models/validations/date_validations.rb
  4. 4
      config/initializers/feature_toggle.rb
  5. 3
      config/locales/en.yml
  6. 5
      db/migrate/20220616130451_add_reference_to_case_log.rb
  7. 5
      db/migrate/20220617102313_add_end_date_to_schemes.rb
  8. 6
      db/schema.rb
  9. 19
      spec/models/case_log_spec.rb
  10. 37
      spec/models/validations/date_validations_spec.rb
  11. 14
      spec/requests/case_logs_controller_spec.rb
  12. 23
      spec/requests/form_controller_spec.rb

1
app/models/case_log.rb

@ -35,6 +35,7 @@ class CaseLog < ApplicationRecord
belongs_to :owning_organisation, class_name: "Organisation", optional: true belongs_to :owning_organisation, class_name: "Organisation", optional: true
belongs_to :managing_organisation, class_name: "Organisation", optional: true belongs_to :managing_organisation, class_name: "Organisation", optional: true
belongs_to :created_by, class_name: "User", optional: true belongs_to :created_by, class_name: "User", optional: true
belongs_to :scheme, optional: true
scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org).or(where(managing_organisation: org)) } scope :filter_by_organisation, ->(org, _user = nil) { where(owning_organisation: org).or(where(managing_organisation: org)) }
scope :filter_by_status, ->(status, _user = nil) { where status: } scope :filter_by_status, ->(status, _user = nil) { where status: }

1
app/models/scheme.rb

@ -1,6 +1,7 @@
class Scheme < ApplicationRecord class Scheme < ApplicationRecord
belongs_to :organisation belongs_to :organisation
has_many :locations has_many :locations
has_many :case_logs
scope :search_by_code, ->(code) { where("code ILIKE ?", "%#{code}%") } scope :search_by_code, ->(code) { where("code ILIKE ?", "%#{code}%") }
scope :search_by_service_name, ->(name) { where("service_name ILIKE ?", "%#{name}%") } scope :search_by_service_name, ->(name) { where("service_name ILIKE ?", "%#{name}%") }

11
app/models/validations/date_validations.rb

@ -34,6 +34,17 @@ module Validations::DateValidations
if record.startdate < first_collection_start_date || record.startdate > second_collection_end_date if record.startdate < first_collection_start_date || record.startdate > second_collection_end_date
record.errors.add :startdate, I18n.t("validations.date.outside_collection_window") record.errors.add :startdate, I18n.t("validations.date.outside_collection_window")
end end
if FeatureToggle.startdate_two_week_validation_enabled? && (record.startdate > Time.zone.today + 14)
record.errors.add :startdate, I18n.t("validations.setup.startdate.later_than_14_days_after")
end
if record.scheme_id.present?
scheme_end_date = record.scheme.end_date
if scheme_end_date.present? && (record.startdate > scheme_end_date)
record.errors.add :startdate, I18n.t("validations.setup.startdate.before_scheme_end_date")
end
end
end end
def validate_sale_completion_date(record) def validate_sale_completion_date(record)

4
config/initializers/feature_toggle.rb

@ -4,4 +4,8 @@ class FeatureToggle
false false
end end
def self.startdate_two_week_validation_enabled?
true
end
end end

3
config/locales/en.yml

@ -61,6 +61,9 @@ en:
setup: setup:
intermediate_rent_product_name: intermediate_rent_product_name:
blank: "Enter name of other intermediate rent product" blank: "Enter name of other intermediate rent product"
startdate:
later_than_14_days_after: "The tenancy start date must not be later than 14 days from today’s date"
before_scheme_end_date: "The tenancy start date must be before the end date for this supported housing scheme"
property: property:
mrcdate: mrcdate:

5
db/migrate/20220616130451_add_reference_to_case_log.rb

@ -0,0 +1,5 @@
class AddReferenceToCaseLog < ActiveRecord::Migration[7.0]
def change
add_reference :case_logs, :scheme, foreign_key: true
end
end

5
db/migrate/20220617102313_add_end_date_to_schemes.rb

@ -0,0 +1,5 @@
class AddEndDateToSchemes < ActiveRecord::Migration[7.0]
def change
add_column :schemes, :end_date, :datetime
end
end

6
db/schema.rb

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_06_14_124115) do ActiveRecord::Schema[7.0].define(version: 2022_06_17_102313) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -198,10 +198,12 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_124115) do
t.integer "hhtype" t.integer "hhtype"
t.integer "new_old" t.integer "new_old"
t.integer "vacdays" t.integer "vacdays"
t.bigint "scheme_id"
t.index ["created_by_id"], name: "index_case_logs_on_created_by_id" t.index ["created_by_id"], name: "index_case_logs_on_created_by_id"
t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id" t.index ["managing_organisation_id"], name: "index_case_logs_on_managing_organisation_id"
t.index ["old_id"], name: "index_case_logs_on_old_id", unique: true t.index ["old_id"], name: "index_case_logs_on_old_id", unique: true
t.index ["owning_organisation_id"], name: "index_case_logs_on_owning_organisation_id" t.index ["owning_organisation_id"], name: "index_case_logs_on_owning_organisation_id"
t.index ["scheme_id"], name: "index_case_logs_on_scheme_id"
end end
create_table "data_protection_confirmations", force: :cascade do |t| create_table "data_protection_confirmations", force: :cascade do |t|
@ -308,6 +310,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_124115) do
t.integer "registered_under_care_act" t.integer "registered_under_care_act"
t.integer "support_type" t.integer "support_type"
t.string "intended_stay" t.string "intended_stay"
t.datetime "end_date"
t.index ["organisation_id"], name: "index_schemes_on_organisation_id" t.index ["organisation_id"], name: "index_schemes_on_organisation_id"
end end
@ -364,6 +367,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_06_14_124115) do
t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
end end
add_foreign_key "case_logs", "schemes"
add_foreign_key "locations", "schemes" add_foreign_key "locations", "schemes"
add_foreign_key "schemes", "organisations" add_foreign_key "schemes", "organisations"
end end

19
spec/models/case_log_spec.rb

@ -1881,9 +1881,14 @@ RSpec.describe CaseLog do
let!(:case_log_2) { FactoryBot.create(:case_log, :completed, startdate: Time.utc(2021, 5, 3), created_by: created_by_user) } let!(:case_log_2) { FactoryBot.create(:case_log, :completed, startdate: Time.utc(2021, 5, 3), created_by: created_by_user) }
before do before do
Timecop.freeze(Time.utc(2022, 6, 3))
FactoryBot.create(:case_log, startdate: Time.utc(2022, 6, 3)) FactoryBot.create(:case_log, startdate: Time.utc(2022, 6, 3))
end end
after do
Timecop.unfreeze
end
context "when searching logs" do context "when searching logs" do
let!(:case_log_to_search) { FactoryBot.create(:case_log, :completed) } let!(:case_log_to_search) { FactoryBot.create(:case_log, :completed) }
@ -1981,6 +1986,14 @@ RSpec.describe CaseLog do
end end
context "when filtering by year" do context "when filtering by year" do
before do
Timecop.freeze(Time.utc(2021, 5, 3))
end
after do
Timecop.unfreeze
end
it "allows filtering on a single year" do it "allows filtering on a single year" do
expect(described_class.filter_by_years(%w[2021]).count).to eq(2) expect(described_class.filter_by_years(%w[2021]).count).to eq(2)
end end
@ -1994,8 +2007,10 @@ RSpec.describe CaseLog do
end end
it "filters based on date boundaries correctly" do it "filters based on date boundaries correctly" do
case_log_1.update!(startdate: Time.zone.local(2022, 4, 1)) case_log_1.startdate = Time.zone.local(2022, 4, 1)
case_log_2.update!(startdate: Time.zone.local(2022, 3, 31)) case_log_1.save!(validate: false)
case_log_2.startdate = Time.zone.local(2022, 3, 31)
case_log_2.save!(validate: false)
expect(described_class.filter_by_years(%w[2021]).count).to eq(1) expect(described_class.filter_by_years(%w[2021]).count).to eq(1)
expect(described_class.filter_by_years(%w[2022]).count).to eq(2) expect(described_class.filter_by_years(%w[2022]).count).to eq(2)

37
spec/models/validations/date_validations_spec.rb

@ -5,6 +5,8 @@ RSpec.describe Validations::DateValidations do
let(:validator_class) { Class.new { include Validations::DateValidations } } let(:validator_class) { Class.new { include Validations::DateValidations } }
let(:record) { FactoryBot.create(:case_log) } let(:record) { FactoryBot.create(:case_log) }
let(:scheme) { FactoryBot.create(:scheme, end_date: Time.zone.today - 5.days) }
let(:scheme_no_end_date) { FactoryBot.create(:scheme, end_date: nil) }
describe "tenancy start date" do describe "tenancy start date" do
it "cannot be before the first collection window start date" do it "cannot be before the first collection window start date" do
@ -30,6 +32,41 @@ RSpec.describe Validations::DateValidations do
date_validator.validate_startdate(record) date_validator.validate_startdate(record)
expect(record.errors["startdate"]).to be_empty expect(record.errors["startdate"]).to be_empty
end end
it "validates that the tenancy start date is before the end date of the chosen scheme if it has an end date" do
record.startdate = Time.zone.today - 3.days
record.scheme = scheme
date_validator.validate_startdate(record)
expect(record.errors["startdate"])
.to include(match I18n.t("validations.setup.startdate.before_scheme_end_date"))
end
it "produces no error when the tenancy start date is before the end date of the chosen scheme if it has an end date" do
record.startdate = Time.zone.today - 30.days
record.scheme = scheme
date_validator.validate_startdate(record)
expect(record.errors["startdate"]).to be_empty
end
it "produces no startdate error for scheme end dates when the chosen scheme does not have an end date" do
record.startdate = Time.zone.today
record.scheme = scheme_no_end_date
date_validator.validate_startdate(record)
expect(record.errors["startdate"]).to be_empty
end
it "validates that the tenancy start date is not later than 14 days from the current date" do
record.startdate = Time.zone.today + 15.days
date_validator.validate_startdate(record)
expect(record.errors["startdate"])
.to include(match I18n.t("validations.setup.startdate.later_than_14_days_after"))
end
it "produces no error when tenancy start date is not later than 14 days from the current date" do
record.startdate = Time.zone.today + 7.days
date_validator.validate_startdate(record)
expect(record.errors["startdate"]).to be_empty
end
end end
describe "major repairs date" do describe "major repairs date" do

14
spec/requests/case_logs_controller_spec.rb

@ -249,12 +249,14 @@ RSpec.describe CaseLogsController, type: :request do
managing_organisation: organisation) managing_organisation: organisation)
end end
let!(:case_log_2022) do let!(:case_log_2022) do
FactoryBot.create(:case_log, :completed, case_log = FactoryBot.build(:case_log, :completed,
owning_organisation: organisation, owning_organisation: organisation,
mrcdate: Time.zone.local(2022, 2, 1), mrcdate: Time.zone.local(2022, 2, 1),
startdate: Time.zone.local(2022, 12, 1), startdate: Time.zone.local(2022, 12, 1),
tenancy: 6, tenancy: 6,
managing_organisation: organisation) managing_organisation: organisation)
case_log.save!(validate: false)
case_log
end end
it "shows case logs for multiple selected years" do it "shows case logs for multiple selected years" do
@ -271,6 +273,14 @@ RSpec.describe CaseLogsController, type: :request do
end end
context "with year and status filter" do context "with year and status filter" do
before do
Timecop.freeze(Time.zone.local(2022, 12, 1))
end
after do
Timecop.unfreeze
end
let!(:case_log_2021) do let!(:case_log_2021) do
FactoryBot.create(:case_log, :in_progress, FactoryBot.create(:case_log, :in_progress,
owning_organisation: organisation, owning_organisation: organisation,
@ -288,7 +298,7 @@ RSpec.describe CaseLogsController, type: :request do
created_by: user) created_by: user)
end end
let!(:case_log_2022_in_progress) do let!(:case_log_2022_in_progress) do
FactoryBot.create(:case_log, :in_progress, FactoryBot.build(:case_log, :in_progress,
owning_organisation: organisation, owning_organisation: organisation,
mrcdate: Time.zone.local(2022, 2, 1), mrcdate: Time.zone.local(2022, 2, 1),
startdate: Time.zone.local(2022, 12, 1), startdate: Time.zone.local(2022, 12, 1),

23
spec/requests/form_controller_spec.rb

@ -37,14 +37,6 @@ RSpec.describe FormController, type: :request do
managing_organisation: organisation, managing_organisation: organisation,
) )
end end
let(:case_log_2022) do
FactoryBot.create(
:case_log,
startdate: Time.zone.local(2022, 12, 1),
owning_organisation: organisation,
managing_organisation: organisation,
)
end
let(:headers) { { "Accept" => "text/html" } } let(:headers) { { "Accept" => "text/html" } }
context "when a user is not signed in" do context "when a user is not signed in" do
@ -112,10 +104,25 @@ RSpec.describe FormController, type: :request do
end end
context "when no other sections are enabled" do context "when no other sections are enabled" do
let(:case_log_2022) do
FactoryBot.create(
:case_log,
startdate: Time.zone.local(2022, 12, 1),
owning_organisation: organisation,
managing_organisation: organisation,
)
end
let(:headers) { { "Accept" => "text/html" } }
before do before do
Timecop.freeze(Time.zone.local(2022, 12, 1))
get "/logs/#{case_log_2022.id}/setup/check-answers", headers: headers, params: {} get "/logs/#{case_log_2022.id}/setup/check-answers", headers: headers, params: {}
end end
after do
Timecop.unfreeze
end
it "does not show Save and go to next incomplete section button" do it "does not show Save and go to next incomplete section button" do
expect(page).not_to have_content("Save and go to next incomplete section") expect(page).not_to have_content("Save and go to next incomplete section")
end end

Loading…
Cancel
Save