From bfb02093a60b246ccda3d688cdfd113a1cfbc0ed Mon Sep 17 00:00:00 2001 From: decabeza Date: Fri, 7 Jul 2023 19:48:23 +0200 Subject: [PATCH] Order expired polls by ends date --- app/models/poll.rb | 21 +++++++++-- spec/models/poll/poll_spec.rb | 62 ++++++++++++++++++--------------- spec/system/polls/polls_spec.rb | 17 +++++++++ 3 files changed, 69 insertions(+), 31 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 86c4667fb..3d587b59f 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -57,8 +57,25 @@ class Poll < ApplicationRecord def self.sort_for_list(user = nil) all.sort do |poll, another_poll| - [poll.weight(user), poll.starts_at, poll.name] <=> - [another_poll.weight(user), another_poll.starts_at, another_poll.name] + compare_polls(poll, another_poll, user) + end + end + + def self.compare_polls(poll, another_poll, user) + weight_comparison = poll.weight(user) <=> another_poll.weight(user) + return weight_comparison unless weight_comparison.zero? + + time_comparison = compare_times(poll, another_poll) + return time_comparison unless time_comparison.zero? + + poll.name <=> another_poll.name + end + + def self.compare_times(poll, another_poll) + if poll.expired? && another_poll.expired? + another_poll.ends_at <=> poll.ends_at + else + poll.starts_at <=> another_poll.starts_at end end diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index dc533e0cb..992c7daa7 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -466,42 +466,46 @@ describe Poll do end describe ".sort_for_list" do - it "returns polls sorted by name ASC" do - starts_at = 1.day.from_now - poll1 = create(:poll, geozone_restricted: true, starts_at: starts_at, name: "Zzz...") - poll2 = create(:poll, geozone_restricted: true, starts_at: starts_at, name: "Mmmm...") - poll3 = create(:poll, geozone_restricted: true, starts_at: starts_at, name: "Aaaaah!") + context "sort polls by weight" do + it "returns poll not restricted by geozone first" do + poll_with_geozone_restricted = create(:poll, geozone_restricted: true) + poll_not_restricted_by_geozone = create(:poll, geozone_restricted: false) - expect(Poll.sort_for_list).to eq [poll3, poll2, poll1] + expect(Poll.sort_for_list).to eq [poll_not_restricted_by_geozone, poll_with_geozone_restricted] + end + + it "returns poll with geozone restricted by user geozone" do + geozone = create(:geozone) + geozone_user = create(:user, :level_two, geozone: geozone) + poll_not_answerable_by_user = create(:poll, geozone_restricted: true) + poll_anserable_by_user = create(:poll, geozone_restricted: true, geozone_restricted_to: [geozone]) + + expect(Poll.sort_for_list(geozone_user)).to eq [poll_anserable_by_user, poll_not_answerable_by_user] + end end - it "returns not geozone restricted polls first" do - starts_at = 1.day.from_now - poll1 = create(:poll, geozone_restricted: false, starts_at: starts_at, name: "Zzz...") - poll2 = create(:poll, geozone_restricted: true, starts_at: starts_at, name: "Aaaaaah!") + context "sort polls by time when weight comparison is zero" do + it "when polls are expired returns the most recently finished first" do + poll_ends_first = create(:poll, ends_at: 1.day.ago - 1.hour) + poll_ends_last = create(:poll, ends_at: 1.day.ago) - expect(Poll.sort_for_list).to eq [poll1, poll2] + expect(Poll.sort_for_list).to eq [poll_ends_last, poll_ends_first] + end + + it "when polls are current returns the most recently started first" do + ends_at = 1.day.from_now + poll_starts_first = create(:poll, starts_at: 1.day.ago - 1.hour, ends_at: ends_at) + poll_starts_last = create(:poll, starts_at: 1.day.ago, ends_at: ends_at) + + expect(Poll.sort_for_list).to eq [poll_starts_first, poll_starts_last] + end end - it "returns polls for the user's geozone first" do - geozone = create(:geozone) - poll1 = create(:poll, geozone_restricted: true) - poll2 = create(:poll, geozone_restricted: true) - poll3 = create(:poll) - poll_geozone_1 = create(:poll, geozone_restricted_to: [geozone]) - poll_geozone_2 = create(:poll, geozone_restricted_to: [geozone]) - geozone_user = create(:user, :level_two, geozone: geozone) + it "sort polls by name ASC when weight and time comparison are zero", :with_frozen_time do + poll1 = create(:poll, name: "Zzz...") + poll2 = create(:poll, name: "Aaaaah!") - expect(Poll.sort_for_list).to eq [poll3, poll1, poll2, poll_geozone_1, poll_geozone_2] - expect(Poll.sort_for_list(geozone_user)).to eq [poll3, poll_geozone_1, poll_geozone_2, poll1, poll2] - end - - it "returns polls earlier to start first" do - starts_at = 1.day.from_now - poll1 = create(:poll, geozone_restricted: false, starts_at: starts_at - 1.hour, name: "Zzz...") - poll2 = create(:poll, geozone_restricted: false, starts_at: starts_at, name: "Aaaaah!") - - expect(Poll.sort_for_list).to eq [poll1, poll2] + expect(Poll.sort_for_list).to eq [poll2, poll1] end it "returns polls with multiple translations only once" do diff --git a/spec/system/polls/polls_spec.rb b/spec/system/polls/polls_spec.rb index ea6cf128c..72a3f60d9 100644 --- a/spec/system/polls/polls_spec.rb +++ b/spec/system/polls/polls_spec.rb @@ -34,6 +34,23 @@ describe "Polls" do end end + scenario "Expired polls are ordered by ends date" do + travel_to "01/07/2023".to_date do + create(:poll, starts_at: "03/05/2023", ends_at: "01/06/2023", name: "Expired poll one") + create(:poll, starts_at: "02/05/2023", ends_at: "02/06/2023", name: "Expired poll two") + create(:poll, starts_at: "01/05/2023", ends_at: "03/06/2023", name: "Expired poll three") + create(:poll, starts_at: "04/05/2023", ends_at: "04/06/2023", name: "Expired poll four") + create(:poll, starts_at: "05/05/2023", ends_at: "05/06/2023", name: "Expired poll five") + + visit polls_path(filter: "expired") + + expect("Expired poll five").to appear_before("Expired poll four") + expect("Expired poll four").to appear_before("Expired poll three") + expect("Expired poll three").to appear_before("Expired poll two") + expect("Expired poll two").to appear_before("Expired poll one") + end + end + scenario "Proposal polls won't be listed" do proposal = create(:proposal) _poll = create(:poll, related: proposal)