Browse Source

refactor status filter into scope

pull/1785/head
Kat 3 years ago
parent
commit
f642268949
  1. 51
      app/models/location.rb
  2. 73
      spec/models/location_spec.rb

51
app/models/location.rb

@ -27,7 +27,52 @@ class Location < ApplicationRecord
scope :active_in_2_weeks, -> { where(confirmed: true).and(started_in_2_weeks) }
scope :confirmed, -> { where(confirmed: true) }
scope :unconfirmed, -> { where.not(confirmed: true) }
scope :filter_by_status, ->(status, _user = nil) { where status: }
scope :filter_by_status, ->(statuses, _user = nil) {
filtered_records = all
scopes = []
statuses.each do |status|
if respond_to?(status, true)
status == "active" ? scopes << send("active_status") : scopes << send(status)
end
end
filtered_records = filtered_records.left_outer_joins(:location_deactivation_periods).merge(scopes.reduce(&:or)) if scopes.any?
filtered_records
}
scope :incomplete, -> {
where(confirmed: false)
}
scope :deactivated, -> {
merge(LocationDeactivationPeriod.deactivations_without_reactivation)
.where("location_deactivation_periods.deactivation_date <= ?", Time.zone.now)
}
scope :deactivating_soon, -> {
merge(LocationDeactivationPeriod.deactivations_without_reactivation)
.where("location_deactivation_periods.deactivation_date > ?", Time.zone.now)
}
scope :reactivating_soon, -> {
where.not("location_deactivation_periods.reactivation_date IS NULL")
.order("location_deactivation_periods.created_at DESC")
.where("location_deactivation_periods.reactivation_date > ?", Time.zone.now)
}
scope :activating_soon, -> {
where("startdate > ?", Time.zone.now)
}
scope :active_status, -> {
where.not(id: joins(:location_deactivation_periods).reactivating_soon.pluck(:id))
.where.not(id: joins(:location_deactivation_periods).deactivated.pluck(:id))
.where.not(id: incomplete.pluck(:id))
.where.not(id: joins(:location_deactivation_periods).deactivating_soon.pluck(:id))
.where.not(id: activating_soon.pluck(:id))
}
LOCAL_AUTHORITIES = LocalAuthority.all.map { |la| [la.name, la.code] }.to_h
@ -99,10 +144,6 @@ class Location < ApplicationRecord
:active
end
def self.filter_by_status(statuses, _user = nil)
where(id: all.select { |record| statuses.include?(record.status.to_s) })
end
def active?
status == :active
end

73
spec/models/location_spec.rb

@ -930,6 +930,79 @@ RSpec.describe Location, type: :model do
end
end
describe "filter by status" do
let!(:incomplete_location) { FactoryBot.create(:location, :incomplete, startdate: Time.zone.local(2022, 4, 1)) }
let!(:active_location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 4, 1)) }
let(:deactivating_soon_location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 4, 1)) }
let(:deactivated_location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 4, 1)) }
let(:reactivating_soon_location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 4, 1)) }
let!(:activating_soon_location) { FactoryBot.create(:location, startdate: Time.zone.local(2022, 7, 7)) }
before do
Timecop.freeze(2022, 6, 7)
FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 8, 8), location: deactivating_soon_location)
deactivating_soon_location.save!
FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 6), location: deactivated_location)
deactivated_location.save!
FactoryBot.create(:location_deactivation_period, deactivation_date: Time.zone.local(2022, 6, 7), reactivation_date: Time.zone.local(2022, 6, 8), location: reactivating_soon_location)
reactivating_soon_location.save!
end
after do
Timecop.unfreeze
end
context "when filtering by incomplete status" do
it "returns only incomplete locations" do
expect(described_class.filter_by_status(["incomplete"]).count).to eq(1)
expect(described_class.filter_by_status(["incomplete"]).first).to eq(incomplete_location)
end
end
context "when filtering by active status" do
it "returns only active locations" do
expect(described_class.filter_by_status(["active"]).count).to eq(1)
expect(described_class.filter_by_status(["active"]).first).to eq(active_location)
end
end
context "when filtering by deactivating_soon status" do
it "returns only deactivating_soon locations" do
expect(described_class.filter_by_status(["deactivating_soon"]).count).to eq(1)
expect(described_class.filter_by_status(["deactivating_soon"]).first).to eq(deactivating_soon_location)
end
end
context "when filtering by deactivated status" do
it "returns only deactivated locations" do
expect(described_class.filter_by_status(["deactivated"]).count).to eq(1)
expect(described_class.filter_by_status(["deactivated"]).first).to eq(deactivated_location)
end
end
context "when filtering by reactivating_soon status" do
it "returns only reactivating_soon locations" do
expect(described_class.filter_by_status(["reactivating_soon"]).count).to eq(1)
expect(described_class.filter_by_status(["reactivating_soon"]).first).to eq(reactivating_soon_location)
end
end
context "when filtering by activating_soon status" do
it "returns only activating_soon locations" do
expect(described_class.filter_by_status(["activating_soon"]).count).to eq(1)
expect(described_class.filter_by_status(["activating_soon"]).first).to eq(activating_soon_location)
end
end
context "when filtering by multiple statuses" do
it "returns only activating_soon locations" do
expect(described_class.filter_by_status(["deactivating_soon", "activating_soon"]).count).to eq(2)
expect(described_class.filter_by_status(["deactivating_soon", "activating_soon"])).to include(activating_soon_location)
expect(described_class.filter_by_status(["deactivating_soon", "activating_soon"])).to include(deactivating_soon_location)
end
end
end
describe "available_from" do
context "when there is a startdate" do
let(:location) { FactoryBot.build(:location, startdate: Time.zone.local(2022, 4, 6)) }

Loading…
Cancel
Save