From 9ab4b573d5f1d38ec52fdbf3a581e89828e13e6f Mon Sep 17 00:00:00 2001 From: Kat Date: Mon, 21 Nov 2022 13:52:33 +0000 Subject: [PATCH] Make deactivate/reactvate location form use location_deactivation_period model --- app/controllers/locations_controller.rb | 44 ++++++------ app/models/location.rb | 51 +------------ app/models/location_deactivation_period.rb | 39 ++++++++++ .../locations/deactivate_confirm.html.erb | 2 +- app/views/locations/toggle_active.html.erb | 2 +- spec/features/schemes_spec.rb | 2 +- spec/helpers/locations_helper_spec.rb | 72 ++++++++++--------- spec/models/location_spec.rb | 22 +++--- spec/requests/locations_controller_spec.rb | 52 +++++++------- 9 files changed, 143 insertions(+), 143 deletions(-) diff --git a/app/controllers/locations_controller.rb b/app/controllers/locations_controller.rb index 5ae052c3b..aaf0678a3 100644 --- a/app/controllers/locations_controller.rb +++ b/app/controllers/locations_controller.rb @@ -21,14 +21,16 @@ class LocationsController < ApplicationController def show; end def new_deactivation - if params[:location].blank? + @location_deactivation_period = LocationDeactivationPeriod.new + + if params[:location_deactivation_period].blank? render "toggle_active", locals: { action: "deactivate" } else - @location.run_deactivation_validations! - @location.deactivation_date = deactivation_date - @location.deactivation_date_type = params[:location][:deactivation_date_type] - if @location.valid? - redirect_to scheme_location_deactivate_confirm_path(@location, deactivation_date: @location.deactivation_date, deactivation_date_type: @location.deactivation_date_type) + @location_deactivation_period.deactivation_date = deactivation_date + @location_deactivation_period.deactivation_date_type = params[:location_deactivation_period][:deactivation_date_type] + @location_deactivation_period.location = @location + if @location_deactivation_period.valid? + redirect_to scheme_location_deactivate_confirm_path(@location, deactivation_date: @location_deactivation_period.deactivation_date, deactivation_date_type: @location_deactivation_period.deactivation_date_type) else render "toggle_active", locals: { action: "deactivate" }, status: :unprocessable_entity end @@ -41,24 +43,24 @@ class LocationsController < ApplicationController end def deactivate - @location.run_deactivation_validations! - - if @location.location_deactivation_periods.create!(deactivation_date:) && update_affected_logs + if LocationDeactivationPeriod.create!(location_id: @location.id, deactivation_date:) && update_affected_logs flash[:notice] = deactivate_success_notice end redirect_to scheme_location_path(@scheme, @location) end def new_reactivation + @location_deactivation_period = LocationDeactivationPeriod.deactivations_without_reactivation.first render "toggle_active", locals: { action: "reactivate" } end def reactivate - @location.run_reactivation_validations! - @location.reactivation_date = reactivation_date - @location.reactivation_date_type = params[:location][:reactivation_date_type] + @location_deactivation_period = LocationDeactivationPeriod.deactivations_without_reactivation.first + + @location_deactivation_period.reactivation_date = reactivation_date + @location_deactivation_period.reactivation_date_type = params[:location_deactivation_period][:reactivation_date_type] - if @location.valid? && @location.location_deactivation_periods.deactivations_without_reactivation.update!(reactivation_date:) + if @location_deactivation_period.update(reactivation_date:) flash[:notice] = reactivate_success_notice redirect_to scheme_location_path(@scheme, @location) else @@ -180,7 +182,7 @@ private end def location_params - required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :add_another_location, :startdate, :mobility_type, :location_admin_district, :location_code, :deactivation_date).merge(scheme_id: @scheme.id) + required_params = params.require(:location).permit(:postcode, :name, :units, :type_of_unit, :add_another_location, :startdate, :mobility_type, :location_admin_district, :location_code).merge(scheme_id: @scheme.id) required_params[:postcode] = PostcodeService.clean(required_params[:postcode]) if required_params[:postcode] required_params end @@ -224,17 +226,17 @@ private end def toggle_date(key) - if params[:location].blank? + if params[:location_deactivation_period].blank? return - elsif params[:location]["#{key}_type".to_sym] == "default" + elsif params[:location_deactivation_period]["#{key}_type".to_sym] == "default" return FormHandler.instance.current_collection_start_date - elsif params[:location][key.to_sym].present? - return params[:location][key.to_sym] + elsif params[:location_deactivation_period][key.to_sym].present? + return params[:location_deactivation_period][key.to_sym] end - day = params[:location]["#{key}(3i)"] - month = params[:location]["#{key}(2i)"] - year = params[:location]["#{key}(1i)"] + day = params[:location_deactivation_period]["#{key}(3i)"] + month = params[:location_deactivation_period]["#{key}(2i)"] + year = params[:location_deactivation_period]["#{key}(1i)"] return nil if [day, month, year].any?(&:blank?) Time.zone.local(year.to_i, month.to_i, day.to_i) if Date.valid_date?(year.to_i, month.to_i, day.to_i) diff --git a/app/models/location.rb b/app/models/location.rb index 70a8c8ede..c05a2351b 100644 --- a/app/models/location.rb +++ b/app/models/location.rb @@ -1,7 +1,5 @@ class Location < ApplicationRecord validate :validate_postcode - validate :deactivation_date_errors - validate :reactivation_date_errors validates :units, :type_of_unit, :mobility_type, presence: true belongs_to :scheme has_many :lettings_logs, class_name: "LettingsLog" @@ -13,7 +11,7 @@ class Location < ApplicationRecord auto_strip_attributes :name - attr_accessor :add_another_location, :deactivation_date_type, :deactivation_date, :run_deactivation_validations, :reactivation_date_type, :reactivation_date, :run_reactivation_validations + attr_accessor :add_another_location scope :search_by_postcode, ->(postcode) { where("REPLACE(postcode, ' ', '') ILIKE ?", "%#{postcode.delete(' ')}%") } scope :search_by_name, ->(name) { where("name ILIKE ?", "%#{name}%") } @@ -394,53 +392,6 @@ class Location < ApplicationRecord status == :reactivating_soon end - def run_deactivation_validations! - @run_deactivation_validations = true - end - - def implicit_run_deactivation_validations - deactivation_date.present? || @run_deactivation_validations - end - - def deactivation_date_errors - return unless implicit_run_deactivation_validations - - if deactivation_date.blank? - if deactivation_date_type.blank? - errors.add(:deactivation_date_type, message: I18n.t("validations.location.toggle_date.not_selected")) - elsif deactivation_date_type == "other" - errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.invalid")) - end - elsif location_deactivation_periods.any? { |period| deactivation_date.between?(period.deactivation_date, period.reactivation_date - 1.day) } - errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation.during_deactivated_period")) - else - unless deactivation_date.between?(available_from, Time.zone.local(2200, 1, 1)) - errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: available_from.to_formatted_s(:govuk_date))) - end - end - end - - def run_reactivation_validations! - @run_reactivation_validations = true - end - - def reactivation_date_errors - return unless @run_reactivation_validations - - recent_deactivation = location_deactivation_periods.deactivations_without_reactivation.first - if reactivation_date.blank? - if reactivation_date_type.blank? - errors.add(:reactivation_date_type, message: I18n.t("validations.location.toggle_date.not_selected")) - elsif reactivation_date_type == "other" - errors.add(:reactivation_date, message: I18n.t("validations.location.toggle_date.invalid")) - end - elsif !reactivation_date.between?(available_from, Time.zone.local(2200, 1, 1)) - errors.add(:reactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: available_from.to_formatted_s(:govuk_date))) - elsif reactivation_date < recent_deactivation.deactivation_date - errors.add(:reactivation_date, message: I18n.t("validations.location.reactivation.before_deactivation", date: recent_deactivation.deactivation_date.to_formatted_s(:govuk_date))) - end - end - private PIO = PostcodeService.new diff --git a/app/models/location_deactivation_period.rb b/app/models/location_deactivation_period.rb index b8579f0bf..9ba88592c 100644 --- a/app/models/location_deactivation_period.rb +++ b/app/models/location_deactivation_period.rb @@ -1,3 +1,42 @@ +class LocationDeactivationPeriodValidator < ActiveModel::Validator + def validate(record) + location = record.location + + if record.deactivation_date.blank? + if record.deactivation_date_type.blank? + record.errors.add(:deactivation_date_type, message: I18n.t("validations.location.toggle_date.not_selected")) + elsif record.deactivation_date_type == "other" + record.errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.invalid")) + end + elsif location.location_deactivation_periods.any? { |period| period.reactivation_date.present? && record.deactivation_date.between?(period.deactivation_date, period.reactivation_date - 1.day) } + record.errors.add(:deactivation_date, message: I18n.t("validations.location.deactivation.during_deactivated_period")) + else + unless record.deactivation_date.between?(location.available_from, Time.zone.local(2200, 1, 1)) + record.errors.add(:deactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: location.available_from.to_formatted_s(:govuk_date))) + end + end + + recent_deactivation = location.location_deactivation_periods.deactivations_without_reactivation.first + if recent_deactivation + if record.reactivation_date.blank? + if record.reactivation_date_type.blank? + record.errors.add(:reactivation_date_type, message: I18n.t("validations.location.toggle_date.not_selected")) + elsif record.reactivation_date_type == "other" + record.errors.add(:reactivation_date, message: I18n.t("validations.location.toggle_date.invalid")) + end + elsif !record.reactivation_date.between?(location.available_from, Time.zone.local(2200, 1, 1)) + record.errors.add(:reactivation_date, message: I18n.t("validations.location.toggle_date.out_of_range", date: location.available_from.to_formatted_s(:govuk_date))) + elsif record.reactivation_date < recent_deactivation.deactivation_date + record.errors.add(:reactivation_date, message: I18n.t("validations.location.reactivation.before_deactivation", date: recent_deactivation.deactivation_date.to_formatted_s(:govuk_date))) + end + end + end +end + class LocationDeactivationPeriod < ApplicationRecord + validates_with LocationDeactivationPeriodValidator + belongs_to :location + attr_accessor :deactivation_date_type, :reactivation_date_type + scope :deactivations_without_reactivation, -> { where(reactivation_date: nil) } end diff --git a/app/views/locations/deactivate_confirm.html.erb b/app/views/locations/deactivate_confirm.html.erb index cbe77b823..47b7bbf60 100644 --- a/app/views/locations/deactivate_confirm.html.erb +++ b/app/views/locations/deactivate_confirm.html.erb @@ -1,4 +1,4 @@ -<%= form_with model: @location, url: scheme_location_deactivate_path(@location), method: "patch", local: true do |f| %> +<%= form_with model: @location_deactivation_period, url: scheme_location_deactivate_path(@location), method: "patch", local: true do |f| %> <% content_for :before_content do %> <%= govuk_back_link(href: :back) %> <% end %> diff --git a/app/views/locations/toggle_active.html.erb b/app/views/locations/toggle_active.html.erb index 017aa93f4..909b335e0 100644 --- a/app/views/locations/toggle_active.html.erb +++ b/app/views/locations/toggle_active.html.erb @@ -8,7 +8,7 @@ ) %> <% end %> -<%= form_with model: @location, url: toggle_location_form_path(action, @location), method: "patch", local: true do |f| %> +<%= form_with model: @location_deactivation_period, url: toggle_location_form_path(action, @location), method: "patch", local: true do |f| %>
<% collection_start_date = FormHandler.instance.current_collection_start_date %> diff --git a/spec/features/schemes_spec.rb b/spec/features/schemes_spec.rb index 257cf27df..797b718af 100644 --- a/spec/features/schemes_spec.rb +++ b/spec/features/schemes_spec.rb @@ -696,7 +696,7 @@ RSpec.describe "Schemes scheme Features" do let!(:deactivated_location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 4, 4), scheme:) } before do - deactivated_location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), location: deactivated_location) click_link(scheme.service_name) end diff --git a/spec/helpers/locations_helper_spec.rb b/spec/helpers/locations_helper_spec.rb index 32306dad0..bccacba3c 100644 --- a/spec/helpers/locations_helper_spec.rb +++ b/spec/helpers/locations_helper_spec.rb @@ -64,18 +64,18 @@ RSpec.describe LocationsHelper do end it "ignores reactivations that were deactivated on the same day" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4)) - location.save! + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 4), location:) + location.reload expect(active_periods(location).count).to eq(1) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 5, 5)) end it "returns sequential non reactivated active periods" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6)) - location.save! + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), location:) + location.reload expect(active_periods(location).count).to eq(2) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 5, 5)) @@ -83,9 +83,9 @@ RSpec.describe LocationsHelper do end it "returns sequential reactivated active periods" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), reactivation_date: Time.zone.local(2022, 8, 5)) - location.save! + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), reactivation_date: Time.zone.local(2022, 8, 5), location:) + location.reload expect(active_periods(location).count).to eq(3) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 5, 5)) expect(active_periods(location).second).to have_attributes(from: Time.zone.local(2022, 6, 4), to: Time.zone.local(2022, 7, 6)) @@ -93,9 +93,9 @@ RSpec.describe LocationsHelper do end it "returns non sequential non reactivated active periods" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), reactivation_date: Time.zone.local(2022, 8, 5)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: nil) - location.save! + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), reactivation_date: Time.zone.local(2022, 8, 5), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: nil, location:) + location.reload expect(active_periods(location).count).to eq(2) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 5, 5)) @@ -103,9 +103,9 @@ RSpec.describe LocationsHelper do end it "returns non sequential reactivated active periods" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), reactivation_date: Time.zone.local(2022, 8, 5)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4)) - location.save! + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 7, 6), reactivation_date: Time.zone.local(2022, 8, 5), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 4), location:) + location.reload expect(active_periods(location).count).to eq(3) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 5, 5)) expect(active_periods(location).second).to have_attributes(from: Time.zone.local(2022, 6, 4), to: Time.zone.local(2022, 7, 6)) @@ -113,8 +113,9 @@ RSpec.describe LocationsHelper do end it "returns correct active periods when reactivation happends during a deactivated period" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 11, 11)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 6), reactivation_date: Time.zone.local(2022, 7, 7)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 11, 11), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 6), reactivation_date: Time.zone.local(2022, 7, 7), location:) + location.reload expect(active_periods(location).count).to eq(2) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 4, 6)) @@ -122,8 +123,9 @@ RSpec.describe LocationsHelper do end it "returns correct active periods when a full deactivation period happens during another deactivation period" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 11)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 6), reactivation_date: Time.zone.local(2022, 7, 7)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 11), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 6), reactivation_date: Time.zone.local(2022, 7, 7), location:) + location.reload expect(active_periods(location).count).to eq(2) expect(active_periods(location).first).to have_attributes(from: Time.zone.local(2022, 4, 1), to: Time.zone.local(2022, 4, 6)) @@ -170,8 +172,9 @@ RSpec.describe LocationsHelper do context "with previous deactivations" do context "and all reactivated deactivations" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: Time.zone.local(2022, 9, 28)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: Time.zone.local(2022, 9, 28), location:) + location.reload end it "displays the timeline of availability" do @@ -183,8 +186,9 @@ RSpec.describe LocationsHelper do context "and non reactivated deactivation" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: nil) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 10), reactivation_date: Time.zone.local(2022, 9, 1), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 15), reactivation_date: nil, location:) + location.reload end it "displays the timeline of availability" do @@ -198,8 +202,9 @@ RSpec.describe LocationsHelper do context "with out of order deactivations" do context "and all reactivated deactivations" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: Time.zone.local(2022, 6, 18)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: Time.zone.local(2022, 6, 18), location:) + location.reload end it "displays the timeline of availability" do @@ -211,8 +216,9 @@ RSpec.describe LocationsHelper do context "and one non reactivated deactivation" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil, location:) + location.reload end it "displays the timeline of availability" do @@ -226,9 +232,10 @@ RSpec.describe LocationsHelper do context "with multiple out of order deactivations" do context "and one non reactivated deactivation" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 24), reactivation_date: Time.zone.local(2022, 10, 28)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 9, 24), reactivation_date: Time.zone.local(2022, 9, 28), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 24), reactivation_date: Time.zone.local(2022, 10, 28), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 15), reactivation_date: nil, location:) + location.reload end it "displays the timeline of availability" do @@ -241,8 +248,9 @@ RSpec.describe LocationsHelper do context "with intersecting deactivations" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 10), reactivation_date: Time.zone.local(2022, 12, 1)) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 11, 11), reactivation_date: Time.zone.local(2022, 12, 11)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 10), reactivation_date: Time.zone.local(2022, 12, 1), location:) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 11, 11), reactivation_date: Time.zone.local(2022, 12, 11), location:) + location.reload end it "displays the timeline of availability" do diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index 53d92013e..64a4855da 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -113,7 +113,7 @@ RSpec.describe Location, type: :model do end describe "status" do - let(:location) { FactoryBot.build(:location) } + let(:location) { FactoryBot.build(:location, startdate: Time.zone.local(2022, 4, 1)) } before do Timecop.freeze(2022, 6, 7) @@ -129,25 +129,25 @@ RSpec.describe Location, type: :model do end it "returns deactivating soon if deactivation_date is in the future" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8), location:) location.save! expect(location.status).to eq(:deactivating_soon) end it "returns deactivated if deactivation_date is in the past" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6), location:) location.save! expect(location.status).to eq(:deactivated) end it "returns deactivated if deactivation_date is today" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), location:) location.save! expect(location.status).to eq(:deactivated) end it "returns reactivating soon if the location has a future reactivation date" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 8)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 8), location:) location.save! expect(location.status).to eq(:reactivating_soon) end @@ -155,7 +155,7 @@ RSpec.describe Location, type: :model do context "when there have been previous deactivations" do before do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 4), reactivation_date: Time.zone.local(2022, 6, 5)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 4), reactivation_date: Time.zone.local(2022, 6, 5), location:) location.save! end @@ -164,33 +164,33 @@ RSpec.describe Location, type: :model do end it "returns deactivating soon if deactivation_date is in the future" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8), location:) location.save! expect(location.status).to eq(:deactivating_soon) end it "returns deactivated if deactivation_date is in the past" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6), location:) location.save! expect(location.status).to eq(:deactivated) end it "returns deactivated if deactivation_date is today" do - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), location:) location.save! expect(location.status).to eq(:deactivated) end it "returns reactivating soon if the location has a future reactivation date" do Timecop.freeze(2022, 6, 8) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 9)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 9), location:) location.save! expect(location.status).to eq(:reactivating_soon) end it "returns if the location had a deactivation during another deactivation" do Timecop.freeze(2022, 6, 4) - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 2)) + FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 6, 2), location:) location.save! expect(location.status).to eq(:reactivating_soon) end diff --git a/spec/requests/locations_controller_spec.rb b/spec/requests/locations_controller_spec.rb index 15e198ac6..c54c53033 100644 --- a/spec/requests/locations_controller_spec.rb +++ b/spec/requests/locations_controller_spec.rb @@ -1257,7 +1257,7 @@ RSpec.describe LocationsController, type: :request do end context "with default date" do - let(:params) { { location: { deactivation_date_type: "default", deactivation_date: } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "default", deactivation_date: } } } it "redirects to the confirmation page" do follow_redirect! @@ -1267,7 +1267,7 @@ RSpec.describe LocationsController, type: :request do end context "with other date" do - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "10", "deactivation_date(1i)": "2022" } } } it "redirects to the confirmation page" do follow_redirect! @@ -1277,7 +1277,7 @@ RSpec.describe LocationsController, type: :request do end context "when confirming deactivation" do - let(:params) { { location: { deactivation_date:, confirm: true, deactivation_date_type: "other" } } } + let(:params) { { location_deactivation_period: { deactivation_date:, confirm: true, deactivation_date_type: "other" } } } before do Timecop.freeze(Time.utc(2022, 10, 10)) @@ -1322,7 +1322,7 @@ RSpec.describe LocationsController, type: :request do end context "when the date is not selected" do - let(:params) { { location: { "deactivation_date": "" } } } + let(:params) { { location_deactivation_period: { "deactivation_date": "" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1331,7 +1331,7 @@ RSpec.describe LocationsController, type: :request do end context "when invalid date is entered" do - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "44", "deactivation_date(1i)": "2022" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1340,7 +1340,7 @@ RSpec.describe LocationsController, type: :request do end context "when the date is entered is before the beginning of current collection window" do - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "10", "deactivation_date(2i)": "4", "deactivation_date(1i)": "2020" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1349,7 +1349,7 @@ RSpec.describe LocationsController, type: :request do end context "when the day is not entered" do - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "", "deactivation_date(2i)": "2", "deactivation_date(1i)": "2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1358,7 +1358,7 @@ RSpec.describe LocationsController, type: :request do end context "when the month is not entered" do - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "", "deactivation_date(1i)": "2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1367,7 +1367,7 @@ RSpec.describe LocationsController, type: :request do end context "when the year is not entered" do - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "2", "deactivation_date(2i)": "2", "deactivation_date(1i)": "" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1377,8 +1377,8 @@ RSpec.describe LocationsController, type: :request do context "when deactivation date is during a deactivated period" do let(:deactivation_date) { Time.zone.local(2022, 10, 10) } - let(:params) { { location: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2022" } } } - let(:add_deactivations) { location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 10, 12)) } + let(:params) { { location_deactivation_period: { deactivation_date_type: "other", "deactivation_date(3i)": "8", "deactivation_date(2i)": "9", "deactivation_date(1i)": "2022" } } } + let(:add_deactivations) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 5, 5), reactivation_date: Time.zone.local(2022, 10, 12), location:) } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1413,7 +1413,7 @@ RSpec.describe LocationsController, type: :request do context "when signed in as a data coordinator" do let(:user) { FactoryBot.create(:user, :data_coordinator) } let!(:scheme) { FactoryBot.create(:scheme, owning_organisation: user.organisation) } - let!(:location) { FactoryBot.create(:location, scheme:) } + let!(:location) { FactoryBot.create(:location, scheme:, startdate: nil) } let(:add_deactivations) { location.location_deactivation_periods << location_deactivation_period } before do @@ -1438,7 +1438,7 @@ RSpec.describe LocationsController, type: :request do end context "with deactivated location" do - let(:location_deactivation_period) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9)) } + let(:location_deactivation_period) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 9), location:) } it "renders reactivate this location" do expect(response).to have_http_status(:ok) @@ -1447,7 +1447,7 @@ RSpec.describe LocationsController, type: :request do end context "with location that's deactivating soon" do - let(:location_deactivation_period) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12)) } + let(:location_deactivation_period) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 10, 12), location:) } it "renders reactivate this location" do expect(response).to have_http_status(:ok) @@ -1456,7 +1456,7 @@ RSpec.describe LocationsController, type: :request do end context "with location that's reactivating soon" do - let(:location_deactivation_period) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 12), reactivation_date: Time.zone.local(2022, 10, 12)) } + let(:location_deactivation_period) { FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 4, 12), reactivation_date: Time.zone.local(2022, 10, 12), location:) } it "renders reactivate this location" do expect(response).to have_http_status(:ok) @@ -1498,7 +1498,7 @@ RSpec.describe LocationsController, type: :request do before do Timecop.freeze(Time.utc(2022, 10, 10)) sign_in user - location.location_deactivation_periods << FactoryBot.create(:location_deactivation_period, deactivation_date:) + FactoryBot.create(:location_deactivation_period, deactivation_date:, location:) location.save! patch "/schemes/#{scheme.id}/locations/#{location.id}/reactivate", params: end @@ -1508,7 +1508,7 @@ RSpec.describe LocationsController, type: :request do end context "with default date" do - let(:params) { { location: { reactivation_date_type: "default" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "default" } } } it "redirects to the location page and displays a success banner" do expect(response).to redirect_to("/schemes/#{scheme.id}/locations/#{location.id}") @@ -1527,7 +1527,7 @@ RSpec.describe LocationsController, type: :request do end context "with other date" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "10", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "10", "reactivation_date(1i)": "2022" } } } it "redirects to the location page and displays a success banner" do expect(response).to redirect_to("/schemes/#{scheme.id}/locations/#{location.id}") @@ -1545,7 +1545,7 @@ RSpec.describe LocationsController, type: :request do end context "with other future date" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "14", "reactivation_date(2i)": "12", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "14", "reactivation_date(2i)": "12", "reactivation_date(1i)": "2022" } } } it "redirects to the location page and displays a success banner" do expect(response).to redirect_to("/schemes/#{scheme.id}/locations/#{location.id}") @@ -1556,7 +1556,7 @@ RSpec.describe LocationsController, type: :request do end context "when the date is not selected" do - let(:params) { { location: { "reactivation_date": "" } } } + let(:params) { { location_deactivation_period: { "reactivation_date": "" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1565,7 +1565,7 @@ RSpec.describe LocationsController, type: :request do end context "when invalid date is entered" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "44", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "44", "reactivation_date(1i)": "2022" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1574,7 +1574,7 @@ RSpec.describe LocationsController, type: :request do end context "when the date is entered is before the beginning of current collection window" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "4", "reactivation_date(1i)": "2020" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "10", "reactivation_date(2i)": "4", "reactivation_date(1i)": "2020" } } } it "displays the new page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1583,7 +1583,7 @@ RSpec.describe LocationsController, type: :request do end context "when the day is not entered" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "", "reactivation_date(2i)": "2", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "", "reactivation_date(2i)": "2", "reactivation_date(1i)": "2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1592,7 +1592,7 @@ RSpec.describe LocationsController, type: :request do end context "when the month is not entered" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "", "reactivation_date(1i)": "2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1601,7 +1601,7 @@ RSpec.describe LocationsController, type: :request do end context "when the year is not entered" do - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "2", "reactivation_date(1i)": "" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "2", "reactivation_date(2i)": "2", "reactivation_date(1i)": "" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity) @@ -1611,7 +1611,7 @@ RSpec.describe LocationsController, type: :request do context "when the reactivation date is before deactivation date" do let(:deactivation_date) { Time.zone.local(2022, 10, 10) } - let(:params) { { location: { reactivation_date_type: "other", "reactivation_date(3i)": "8", "reactivation_date(2i)": "9", "reactivation_date(1i)": "2022" } } } + let(:params) { { location_deactivation_period: { reactivation_date_type: "other", "reactivation_date(3i)": "8", "reactivation_date(2i)": "9", "reactivation_date(1i)": "2022" } } } it "displays page with an error message" do expect(response).to have_http_status(:unprocessable_entity)