Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Order proposals by my votes #18

Merged
merged 2 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# frozen_string_literal: true

module Decidim
module DecidimAwesome
module Proposals
module OrderableOverride
extend ActiveSupport::Concern

included do
private

def possible_orders
@possible_orders ||= begin
possible_orders = %w(random recent)
possible_orders << "supported_first" if supported_order_available?
possible_orders << "supported_last" if supported_order_available?
possible_orders << "most_voted" if most_voted_order_available?
possible_orders << "most_endorsed" if current_settings.endorsements_enabled?
possible_orders << "most_commented" if component_settings.comments_enabled?
possible_orders << "most_followed" << "with_more_authors"
possible_orders
end
end

# rubocop:disable Metrics/CyclomaticComplexity
def reorder(proposals)
case order
when "supported_first"
proposals.joins(my_votes_join).group(:id).order(Arel.sql("COUNT(decidim_proposals_proposal_votes.id) DESC"))
when "supported_last"
proposals.joins(my_votes_join).group(:id).order(Arel.sql("COUNT(decidim_proposals_proposal_votes.id) ASC"))
when "most_commented"
proposals.left_joins(:comments).group(:id).order(Arel.sql("COUNT(decidim_comments_comments.id) DESC"))
when "most_endorsed"
proposals.order(endorsements_count: :desc)
when "most_followed"
proposals.left_joins(:follows).group(:id).order(Arel.sql("COUNT(decidim_follows.id) DESC"))
when "most_voted"
proposals.order(proposal_votes_count: :desc)
when "random"
proposals.order_randomly(random_seed)
when "recent"
proposals.order(published_at: :desc)
when "with_more_authors"
proposals.order(coauthorships_count: :desc)
end
end
# rubocop:enable Metrics/CyclomaticComplexity

def my_votes_join
votes_table = Decidim::Proposals::ProposalVote.arel_table
proposals_table = Decidim::Proposals::Proposal.arel_table
Arel::Nodes::OuterJoin.new(
votes_table,
Arel::Nodes::On.new(
votes_table[:decidim_proposal_id].eq(proposals_table[:id])
.and(votes_table[:decidim_author_id].eq(current_user.id))
)
)
end

def supported_order_available?
most_voted_order_available? && current_user
end
end
end
end
end
end
5 changes: 5 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,11 @@ en:
weight_1: Red
weight_2: Yellow
weight_3: Green
proposals:
proposals:
orders:
supported_first: Supported first
supported_last: Supported last
layouts:
decidim:
admin:
Expand Down
1 change: 1 addition & 0 deletions lib/decidim/decidim_awesome/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class Engine < ::Rails::Engine

if DecidimAwesome.enabled?(:weighted_proposal_voting)
Decidim::Proposals::ProposalVotesController.include(Decidim::DecidimAwesome::Proposals::ProposalVotesControllerOverride)
Decidim::Proposals::ProposalsController.include(Decidim::DecidimAwesome::Proposals::OrderableOverride)
end
end
end
Expand Down
98 changes: 98 additions & 0 deletions spec/controllers/proposals_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim::Proposals
describe ProposalsController, type: :controller do
routes { Decidim::Proposals::Engine.routes }

let(:component) { create(:proposal_component, :with_votes_enabled) }
let!(:proposal) { create(:proposal, component: component) }
let!(:proposal2) { create(:proposal, component: component) }
let!(:proposal3) { create(:proposal, component: component) }
let(:user) { create(:user, :confirmed, organization: component.organization) }
let!(:vote1) { create(:proposal_vote, proposal: proposal2, author: user) }
let!(:vote2) { create(:proposal_vote, proposal: proposal3, author: user) }

let(:params) do
{
proposal_id: proposal.id,
component_id: component.id
}
end

before do
request.env["decidim.current_organization"] = component.organization
request.env["decidim.current_participatory_space"] = component.participatory_space
request.env["decidim.current_component"] = component
sign_in user
end

describe "GET index" do
it "has order filters" do
get :index, params: params

expect(response).to have_http_status(:ok)
expect(controller.helpers.available_orders).to eq(%w(random recent supported_first supported_last most_voted most_endorsed most_commented most_followed with_more_authors))
end

context "when supported_first order" do
let(:params) do
{
proposal_id: proposal.id,
component_id: component.id,
order: "supported_first"
}
end

it "orders by supported_first" do
get :index, params: params

expect(response).to have_http_status(:ok)
expect(assigns(:proposals).to_a).to eq([proposal2, proposal3, proposal])
end
end

context "when supported_last order" do
let(:params) do
{
proposal_id: proposal.id,
component_id: component.id,
order: "supported_last"
}
end

it "orders by supported_last" do
get :index, params: params

expect(response).to have_http_status(:ok)
expect(assigns(:proposals).to_a).to eq([proposal, proposal2, proposal3])
end
end

context "when no votes enabled" do
let(:component) { create(:proposal_component, :with_votes_disabled) }

it "has order filters" do
get :index, params: params

expect(response).to have_http_status(:ok)
expect(controller.helpers.available_orders).to eq(%w(random recent most_endorsed most_commented most_followed with_more_authors))
end
end

context "when no current_user" do
before do
allow(controller).to receive(:current_user).and_return(nil)
end

it "has order filters" do
get :index, params: params

expect(response).to have_http_status(:ok)
expect(controller.helpers.available_orders).to eq(%w(random recent most_voted most_endorsed most_commented most_followed with_more_authors))
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/controllers/proposals_votes_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ module Decidim::Proposals
end
end

describe "destroy" do
describe "DELETE destroy" do
before do
create(:proposal_vote, proposal: proposal, author: user)
end
Expand Down
Loading