Merge pull request #5118 from consuldemocracy/undo-votes
Allow undoing "like/unlike" votes
This commit is contained in:
@@ -25,10 +25,10 @@
|
||||
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:active {
|
||||
&:active,
|
||||
&[aria-pressed=true] {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,8 @@
|
||||
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:active {
|
||||
&:active,
|
||||
&[aria-pressed=true] {
|
||||
background: $like;
|
||||
border: 2px solid $like;
|
||||
}
|
||||
@@ -50,19 +51,14 @@
|
||||
|
||||
&:not([disabled]) {
|
||||
&:hover,
|
||||
&:active {
|
||||
&:active,
|
||||
&[aria-pressed=true] {
|
||||
background: $unlike;
|
||||
border: 2px solid $unlike;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.like,
|
||||
.unlike {
|
||||
vertical-align: super;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.percentage {
|
||||
display: inline-block;
|
||||
font-size: $small-font-size;
|
||||
@@ -76,22 +72,4 @@
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.voted {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.in-favor .voted {
|
||||
background: $like;
|
||||
border: 2px solid $like;
|
||||
}
|
||||
|
||||
.against .voted {
|
||||
background: $unlike;
|
||||
border: 2px solid $unlike;
|
||||
}
|
||||
|
||||
.no-voted {
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1705,7 +1705,8 @@ table {
|
||||
.in-favor button {
|
||||
@include has-fa-icon(thumbs-up, solid);
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&[aria-pressed=true] {
|
||||
color: $like;
|
||||
}
|
||||
}
|
||||
@@ -1713,7 +1714,8 @@ table {
|
||||
.against button {
|
||||
@include has-fa-icon(thumbs-down, solid);
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&[aria-pressed=true] {
|
||||
color: $unlike;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,22 +3,16 @@
|
||||
|
|
||||
|
||||
<span class="in-favor">
|
||||
<%= button_to vote_comment_path(comment, value: "yes"),
|
||||
method: "post",
|
||||
remote: can?(:vote, comment),
|
||||
title: t("votes.agree") do %>
|
||||
<span class="show-for-sr"><%= t("votes.agree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(comment,
|
||||
value: "yes",
|
||||
title: t("votes.agree")) %>
|
||||
<%= comment.total_likes %>
|
||||
</span>
|
||||
|
||||
<span class="against">
|
||||
<%= button_to vote_comment_path(comment, value: "no"),
|
||||
method: "post",
|
||||
remote: can?(:vote, comment),
|
||||
title: t("votes.disagree") do %>
|
||||
<span class="show-for-sr"><%= t("votes.disagree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(comment,
|
||||
value: "no",
|
||||
title: t("votes.disagree")) %>
|
||||
<%= comment.total_dislikes %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
class Comments::VotesComponent < ApplicationComponent
|
||||
attr_reader :comment
|
||||
delegate :can?, to: :helpers
|
||||
|
||||
def initialize(comment)
|
||||
@comment = comment
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Legislation::Proposals::VotesComponent < ApplicationComponent
|
||||
attr_reader :proposal
|
||||
delegate :current_user, :link_to_verify_account, to: :helpers
|
||||
delegate :current_user, :link_to_verify_account, :can?, to: :helpers
|
||||
|
||||
def initialize(proposal)
|
||||
@proposal = proposal
|
||||
@@ -9,7 +9,7 @@ class Legislation::Proposals::VotesComponent < ApplicationComponent
|
||||
private
|
||||
|
||||
def can_vote?
|
||||
proposal.votable_by?(current_user)
|
||||
can?(:create, proposal.votes_for.new(voter: current_user))
|
||||
end
|
||||
|
||||
def cannot_vote_text
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
<div class="in-favor-against">
|
||||
<div class="in-favor">
|
||||
<%= button_to polymorphic_path(votable, action: :vote, value: "yes"),
|
||||
class: "like #{voted_classes[:in_favor]}",
|
||||
title: t("votes.agree"),
|
||||
"aria-label": agree_aria_label,
|
||||
method: "post",
|
||||
remote: true do %>
|
||||
<span class="show-for-sr"><%= t("votes.agree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(votable,
|
||||
value: "yes",
|
||||
"aria-label": agree_aria_label,
|
||||
title: t("votes.agree")) %>
|
||||
<span class="percentage"><%= votes_percentage("likes", votable) %></span>
|
||||
</div>
|
||||
|
||||
<div class="against">
|
||||
<%= button_to polymorphic_path(votable, action: :vote, value: "no"),
|
||||
class: "unlike #{voted_classes[:against]}",
|
||||
title: t("votes.disagree"),
|
||||
"aria-label": disagree_aria_label,
|
||||
method: "post",
|
||||
remote: true do %>
|
||||
<span class="show-for-sr"><%= t("votes.disagree") %></span>
|
||||
<% end %>
|
||||
<%= render Shared::VoteButtonComponent.new(votable,
|
||||
value: "no",
|
||||
"aria-label": disagree_aria_label,
|
||||
title: t("votes.disagree")) %>
|
||||
<span class="percentage"><%= votes_percentage("dislikes", votable) %></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Shared::InFavorAgainstComponent < ApplicationComponent
|
||||
attr_reader :votable
|
||||
delegate :current_user, :votes_percentage, to: :helpers
|
||||
delegate :votes_percentage, to: :helpers
|
||||
|
||||
def initialize(votable)
|
||||
@votable = votable
|
||||
@@ -8,21 +8,6 @@ class Shared::InFavorAgainstComponent < ApplicationComponent
|
||||
|
||||
private
|
||||
|
||||
def voted_classes
|
||||
@voted_classes ||= css_classes_for_vote
|
||||
end
|
||||
|
||||
def css_classes_for_vote
|
||||
case current_user&.voted_as_when_voted_for(votable)
|
||||
when true
|
||||
{ in_favor: "voted", against: "no-voted" }
|
||||
when false
|
||||
{ in_favor: "no-voted", against: "voted" }
|
||||
else
|
||||
{ in_favor: "", against: "" }
|
||||
end
|
||||
end
|
||||
|
||||
def agree_aria_label
|
||||
t("votes.agree_label", title: votable.title)
|
||||
end
|
||||
|
||||
3
app/components/shared/vote_button_component.html.erb
Normal file
3
app/components/shared/vote_button_component.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<%= button_to path, default_options.merge(options) do %>
|
||||
<span class="show-for-sr"><%= options[:title] %></span>
|
||||
<% end %>
|
||||
48
app/components/shared/vote_button_component.rb
Normal file
48
app/components/shared/vote_button_component.rb
Normal file
@@ -0,0 +1,48 @@
|
||||
class Shared::VoteButtonComponent < ApplicationComponent
|
||||
attr_reader :votable, :value, :options
|
||||
delegate :current_user, :can?, to: :helpers
|
||||
|
||||
def initialize(votable, value:, **options)
|
||||
@votable = votable
|
||||
@value = value
|
||||
@options = options
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def path
|
||||
if already_voted?
|
||||
polymorphic_path(vote)
|
||||
else
|
||||
polymorphic_path(vote, value: value)
|
||||
end
|
||||
end
|
||||
|
||||
def default_options
|
||||
if already_voted?
|
||||
{
|
||||
"aria-pressed": true,
|
||||
method: :delete,
|
||||
remote: can?(:destroy, vote)
|
||||
}
|
||||
else
|
||||
{
|
||||
"aria-pressed": false,
|
||||
method: :post,
|
||||
remote: can?(:create, vote)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def vote
|
||||
@vote ||= Vote.find_or_initialize_by(votable: votable, voter: current_user, vote_flag: parsed_value)
|
||||
end
|
||||
|
||||
def already_voted?
|
||||
vote.persisted?
|
||||
end
|
||||
|
||||
def parsed_value
|
||||
value == "yes"
|
||||
end
|
||||
end
|
||||
35
app/controllers/comments/votes_controller.rb
Normal file
35
app/controllers/comments/votes_controller.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
module Comments
|
||||
class VotesController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
load_and_authorize_resource :comment
|
||||
load_and_authorize_resource through: :comment, through_association: :votes_for, only: :destroy
|
||||
before_action :verify_comments_open!
|
||||
|
||||
def create
|
||||
authorize! :create, Vote.new(voter: current_user, votable: @comment)
|
||||
@comment.vote_by(voter: current_user, vote: params[:value])
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :show }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@comment.unvote_by(current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :show }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def verify_comments_open!
|
||||
return if current_user.administrator? || current_user.moderator?
|
||||
|
||||
if @comment.commentable.respond_to?(:comments_closed?) && @comment.commentable.comments_closed?
|
||||
redirect_to polymorphic_path(@comment.commentable), alert: t("comments.comments_closed")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,8 +1,8 @@
|
||||
class CommentsController < ApplicationController
|
||||
before_action :authenticate_user!, only: [:create, :hide, :vote]
|
||||
before_action :authenticate_user!, only: [:create, :hide]
|
||||
before_action :load_commentable, only: :create
|
||||
before_action :verify_resident_for_commentable!, only: :create
|
||||
before_action :verify_comments_open!, only: [:create, :vote]
|
||||
before_action :verify_comments_open!, only: [:create]
|
||||
before_action :build_comment, only: :create
|
||||
|
||||
load_and_authorize_resource
|
||||
@@ -27,11 +27,6 @@ class CommentsController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def vote
|
||||
@comment.vote_by(voter: current_user, vote: params[:value])
|
||||
respond_with @comment
|
||||
end
|
||||
|
||||
def flag
|
||||
Flag.flag(current_user, @comment)
|
||||
set_comment_flags(@comment)
|
||||
|
||||
24
app/controllers/debates/votes_controller.rb
Normal file
24
app/controllers/debates/votes_controller.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
module Debates
|
||||
class VotesController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
load_and_authorize_resource :debate
|
||||
load_and_authorize_resource through: :debate, through_association: :votes_for, only: :destroy
|
||||
|
||||
def create
|
||||
authorize! :create, Vote.new(voter: current_user, votable: @debate)
|
||||
@debate.register_vote(current_user, params[:value])
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :show }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@debate.unvote_by(current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :show }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,10 +28,6 @@ class DebatesController < ApplicationController
|
||||
redirect_to debate_path(@debate), status: :moved_permanently if request.path != debate_path(@debate)
|
||||
end
|
||||
|
||||
def vote
|
||||
@debate.register_vote(current_user, params[:value])
|
||||
end
|
||||
|
||||
def unmark_featured
|
||||
@debate.update!(featured_at: nil)
|
||||
redirect_to debates_path
|
||||
|
||||
29
app/controllers/legislation/proposals/votes_controller.rb
Normal file
29
app/controllers/legislation/proposals/votes_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
module Legislation
|
||||
module Proposals
|
||||
class VotesController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
load_and_authorize_resource :process, class: "Legislation::Process"
|
||||
load_and_authorize_resource :proposal, class: "Legislation::Proposal",
|
||||
through: :process,
|
||||
id_param: "legislation_proposal_id"
|
||||
load_and_authorize_resource through: :proposal, through_association: :votes_for, only: :destroy
|
||||
|
||||
def create
|
||||
authorize! :create, Vote.new(voter: current_user, votable: @proposal)
|
||||
@proposal.vote_by(voter: current_user, vote: params[:value])
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :show }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@proposal.unvote_by(current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :show }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -37,10 +37,6 @@ class Legislation::ProposalsController < Legislation::BaseController
|
||||
end
|
||||
end
|
||||
|
||||
def vote
|
||||
@proposal.register_vote(current_user, params[:value])
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def proposal_params
|
||||
|
||||
@@ -81,14 +81,15 @@ module Abilities
|
||||
can [:create, :destroy], DirectUpload
|
||||
|
||||
unless user.organization?
|
||||
can :vote, Debate
|
||||
can :vote, Comment
|
||||
can [:create, :destroy], ActsAsVotable::Vote, voter_id: user.id, votable_type: "Debate"
|
||||
can [:create, :destroy], ActsAsVotable::Vote, voter_id: user.id, votable_type: "Comment"
|
||||
end
|
||||
|
||||
if user.level_two_or_three_verified?
|
||||
can :vote, Proposal, &:published?
|
||||
|
||||
can :vote, Legislation::Proposal
|
||||
can [:create, :destroy], ActsAsVotable::Vote, voter_id: user.id, votable_type: "Legislation::Proposal"
|
||||
|
||||
can :create, Legislation::Answer
|
||||
|
||||
can :create, Budget::Investment, budget: { phase: "accepting" }
|
||||
|
||||
@@ -286,7 +286,7 @@ class Budget
|
||||
def permission_problem(user)
|
||||
return :not_logged_in unless user
|
||||
return :organization if user.organization?
|
||||
return :not_verified unless user.can?(:create, ActsAsVotable::Vote)
|
||||
return :not_verified unless user.level_two_or_three_verified?
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -108,14 +108,6 @@ class Legislation::Proposal < ApplicationRecord
|
||||
author_id == user.id && editable?
|
||||
end
|
||||
|
||||
def votable_by?(user)
|
||||
user&.level_two_or_three_verified?
|
||||
end
|
||||
|
||||
def register_vote(user, vote_value)
|
||||
vote_by(voter: user, vote: vote_value) if votable_by?(user)
|
||||
end
|
||||
|
||||
def code
|
||||
"#{Setting["proposal_code_prefix"]}-#{created_at.strftime("%Y-%m")}-#{id}"
|
||||
end
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
<div id="<%= dom_id(comment) %>_reply" class="reply">
|
||||
<% unless valuation %>
|
||||
<div id="<%= dom_id(comment) %>_votes" class="comment-votes float-right">
|
||||
<%= render "comments/votes", comment: comment %>
|
||||
<%= render Comments::VotesComponent.new(comment) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<%= render Comments::VotesComponent.new(comment) %>
|
||||
@@ -1 +0,0 @@
|
||||
$("#<%= dom_id(@comment) %>_votes").html("<%= j render("comments/votes", comment: @comment) %>");
|
||||
1
app/views/comments/votes/show.js.erb
Normal file
1
app/views/comments/votes/show.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#<%= dom_id(@comment) %>_votes").html("<%= j render Comments::VotesComponent.new(@comment) %>");
|
||||
@@ -49,7 +49,7 @@
|
||||
</div>
|
||||
|
||||
<div id="<%= dom_id(debate) %>_votes" class="small-12 medium-3 column">
|
||||
<%= render "debates/votes", debate: debate %>
|
||||
<%= render Debates::VotesComponent.new(debate) %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<%= render Debates::VotesComponent.new(debate) %>
|
||||
@@ -57,7 +57,7 @@
|
||||
<div class="sidebar-divider"></div>
|
||||
<h2><%= t("votes.supports") %></h2>
|
||||
<div id="<%= dom_id(@debate) %>_votes">
|
||||
<%= render "debates/votes", debate: @debate %>
|
||||
<%= render Debates::VotesComponent.new(@debate) %>
|
||||
</div>
|
||||
<%= render "shared/social_share",
|
||||
share_title: t("debates.show.share"),
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
$("#<%= dom_id(@debate) %>_votes").html("<%= j render("debates/votes", debate: @debate) %>");
|
||||
1
app/views/debates/votes/show.js.erb
Normal file
1
app/views/debates/votes/show.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#<%= dom_id(@debate) %>_votes").html("<%= j render Debates::VotesComponent.new(@debate) %>");
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="comment-votes">
|
||||
<div id="<%= dom_id(comment) %>_votes" class="comment-votes float-right">
|
||||
<%= render "comments/votes", comment: comment %>
|
||||
<%= render Comments::VotesComponent.new(comment) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
resources :comments, only: [:create, :show], shallow: true do
|
||||
resources :comments, only: [:create, :show] do
|
||||
member do
|
||||
post :vote
|
||||
put :flag
|
||||
put :unflag
|
||||
put :hide
|
||||
end
|
||||
|
||||
resources :votes, controller: "comments/votes", only: [:create, :destroy]
|
||||
end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
resources :debates do
|
||||
member do
|
||||
post :vote
|
||||
put :flag
|
||||
put :unflag
|
||||
put :mark_featured
|
||||
@@ -11,4 +10,6 @@ resources :debates do
|
||||
get :suggest
|
||||
put "recommendations/disable", only: :index, controller: "debates", action: :disable_recommendations
|
||||
end
|
||||
|
||||
resources :votes, controller: "debates/votes", only: [:create, :destroy]
|
||||
end
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace :legislation do
|
||||
|
||||
resources :proposals, except: [:index] do
|
||||
member do
|
||||
post :vote
|
||||
put :flag
|
||||
put :unflag
|
||||
end
|
||||
@@ -25,6 +24,10 @@ namespace :legislation do
|
||||
end
|
||||
end
|
||||
|
||||
resources :legislation_proposals, path: "proposals", only: [] do
|
||||
resources :votes, controller: "proposals/votes", only: [:create, :destroy]
|
||||
end
|
||||
|
||||
resources :draft_versions, only: [:show] do
|
||||
get :go_to_version, on: :collection
|
||||
get :changes
|
||||
@@ -41,6 +44,10 @@ resolve "Legislation::Proposal" do |proposal, options|
|
||||
[proposal.process, :proposal, options.merge(id: proposal)]
|
||||
end
|
||||
|
||||
resolve "Vote" do |vote, options|
|
||||
[*resource_hierarchy_for(vote.votable), vote, options]
|
||||
end
|
||||
|
||||
resolve "Legislation::Question" do |question, options|
|
||||
[question.process, :question, options.merge(id: question)]
|
||||
end
|
||||
|
||||
65
spec/components/comments/votes_component_spec.rb
Normal file
65
spec/components/comments/votes_component_spec.rb
Normal file
@@ -0,0 +1,65 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Comments::VotesComponent do
|
||||
let(:user) { create(:user) }
|
||||
let(:comment) { create(:comment, user: user) }
|
||||
let(:component) { Comments::VotesComponent.new(comment) }
|
||||
|
||||
describe "aria-pressed and method attributes" do
|
||||
it "have expected values when the in-favor button is pressed" do
|
||||
comment.vote_by(voter: user, vote: "yes")
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
page.find(".in-favor") do |in_favor_block|
|
||||
expect(in_favor_block).to have_css "button[aria-pressed='true']"
|
||||
expect(in_favor_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(in_favor_block).to have_css "input[name='_method'][value='delete']", visible: :hidden
|
||||
end
|
||||
|
||||
page.find(".against") do |against_block|
|
||||
expect(against_block).to have_css "button[aria-pressed='false']"
|
||||
expect(against_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(against_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
end
|
||||
|
||||
it "have expected values when the against button is pressed" do
|
||||
comment.vote_by(voter: user, vote: "no")
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
page.find(".in-favor") do |in_favor_block|
|
||||
expect(in_favor_block).to have_css "button[aria-pressed='false']"
|
||||
expect(in_favor_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(in_favor_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
|
||||
page.find(".against") do |against_block|
|
||||
expect(against_block).to have_css "button[aria-pressed='true']"
|
||||
expect(against_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(against_block).to have_css "input[name='_method'][value='delete']", visible: :hidden
|
||||
end
|
||||
end
|
||||
|
||||
it "have expected values when neither the 'in-favor' button nor the 'against' button are pressed" do
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
page.find(".in-favor") do |in_favor_block|
|
||||
expect(in_favor_block).to have_css "button[aria-pressed='false']"
|
||||
expect(in_favor_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(in_favor_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
|
||||
page.find(".against") do |against_block|
|
||||
expect(against_block).to have_css "button[aria-pressed='false']"
|
||||
expect(against_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(against_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -25,19 +25,5 @@ describe Debates::VotesComponent do
|
||||
expect(page).to have_button "I don't agree with What about the 2030 agenda?"
|
||||
expect(page).not_to have_content "You must sign in or sign up to continue."
|
||||
end
|
||||
|
||||
it "does not include result percentages" do
|
||||
create(:vote, votable: debate)
|
||||
sign_in(create(:user))
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_button count: 2
|
||||
expect(page).to have_button "I agree"
|
||||
expect(page).to have_button "I disagree"
|
||||
expect(page).not_to have_button text: "%"
|
||||
expect(page).not_to have_button text: "100"
|
||||
expect(page).not_to have_button text: "0"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,19 +38,5 @@ describe Legislation::Proposals::VotesComponent do
|
||||
expect(page).to have_button "I don't agree with Require wearing masks at home"
|
||||
expect(page).not_to have_content "You must sign in or sign up to continue."
|
||||
end
|
||||
|
||||
it "does not include result percentages" do
|
||||
create(:vote, votable: proposal)
|
||||
sign_in(create(:user))
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_button count: 2
|
||||
expect(page).to have_button "I agree"
|
||||
expect(page).to have_button "I disagree"
|
||||
expect(page).not_to have_button text: "%"
|
||||
expect(page).not_to have_button text: "100"
|
||||
expect(page).not_to have_button text: "0"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
88
spec/components/shared/in_favor_against_component_spec.rb
Normal file
88
spec/components/shared/in_favor_against_component_spec.rb
Normal file
@@ -0,0 +1,88 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Shared::InFavorAgainstComponent do
|
||||
let(:debate) { create(:debate) }
|
||||
let(:component) { Shared::InFavorAgainstComponent.new(debate) }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
describe "Agree and disagree buttons" do
|
||||
it "can create a vote when the user has not yet voted" do
|
||||
sign_in user
|
||||
|
||||
render_inline component
|
||||
|
||||
page.find(".in-favor") do |in_favor_block|
|
||||
expect(in_favor_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(in_favor_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
|
||||
page.find(".against") do |against_block|
|
||||
expect(against_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(against_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
end
|
||||
|
||||
it "can undo vote when the user has already voted" do
|
||||
create(:vote, votable: debate, voter: user)
|
||||
|
||||
sign_in user
|
||||
|
||||
render_inline component
|
||||
|
||||
page.find(".in-favor") do |in_favor_block|
|
||||
expect(in_favor_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(in_favor_block).to have_css "input[name='_method'][value='delete']", visible: :hidden
|
||||
end
|
||||
|
||||
page.find(".against") do |against_block|
|
||||
expect(against_block).to have_css "form[action*='votes'][method='post']"
|
||||
expect(against_block).not_to have_css "input[name='_method']", visible: :all
|
||||
end
|
||||
end
|
||||
|
||||
it "does not include result percentages" do
|
||||
create(:vote, votable: debate)
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_button count: 2
|
||||
expect(page).to have_button "I agree"
|
||||
expect(page).to have_button "I disagree"
|
||||
expect(page).not_to have_button text: "%"
|
||||
expect(page).not_to have_button text: "100"
|
||||
expect(page).not_to have_button text: "0"
|
||||
end
|
||||
|
||||
describe "aria-pressed attribute" do
|
||||
it "is true when the in-favor button is pressed" do
|
||||
debate.register_vote(user, "yes")
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page.find(".in-favor")).to have_css "button[aria-pressed='true']"
|
||||
expect(page.find(".against")).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
it "is true when the against button is pressed" do
|
||||
debate.register_vote(user, "no")
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page.find(".in-favor")).to have_css "button[aria-pressed='false']"
|
||||
expect(page.find(".against")).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
|
||||
it "is false when neither the 'in-favor' button nor the 'against' button are pressed" do
|
||||
sign_in(user)
|
||||
|
||||
render_inline component
|
||||
|
||||
expect(page.find(".in-favor")).to have_css "button[aria-pressed='false']"
|
||||
expect(page.find(".against")).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
34
spec/controllers/comments/votes_controller_spec.rb
Normal file
34
spec/controllers/comments/votes_controller_spec.rb
Normal file
@@ -0,0 +1,34 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Comments::VotesController do
|
||||
let(:comment) { create(:comment) }
|
||||
|
||||
describe "POST create" do
|
||||
it "allows voting" do
|
||||
sign_in create(:user)
|
||||
|
||||
expect do
|
||||
post :create, xhr: true, params: { comment_id: comment.id, value: "yes" }
|
||||
end.to change { comment.reload.votes_for.size }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE destroy" do
|
||||
let(:user) { create(:user) }
|
||||
let!(:vote) { create(:vote, votable: comment, voter: user) }
|
||||
|
||||
it "redirects unidentified users to the sign in page" do
|
||||
delete :destroy, params: { comment_id: comment.id, id: vote }
|
||||
|
||||
expect(response).to redirect_to new_user_session_path
|
||||
end
|
||||
|
||||
it "allows undoing a vote" do
|
||||
sign_in user
|
||||
|
||||
expect do
|
||||
delete :destroy, xhr: true, params: { comment_id: comment.id, id: vote }
|
||||
end.to change { comment.reload.votes_for.size }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
56
spec/controllers/debates/votes_controller_spec.rb
Normal file
56
spec/controllers/debates/votes_controller_spec.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Debates::VotesController do
|
||||
describe "POST create" do
|
||||
it "does not authorize unauthenticated users" do
|
||||
debate = create(:debate)
|
||||
|
||||
post :create, xhr: true, params: { debate_id: debate.id, value: "yes" }
|
||||
|
||||
expect(response).to be_unauthorized
|
||||
end
|
||||
|
||||
it "redirects unauthenticated users without JavaScript to the sign in page" do
|
||||
debate = create(:debate)
|
||||
|
||||
post :create, params: { debate_id: debate.id, value: "yes" }
|
||||
|
||||
expect(response).to redirect_to new_user_session_path
|
||||
end
|
||||
|
||||
describe "Vote with too many anonymous votes" do
|
||||
it "allows vote if user is allowed" do
|
||||
Setting["max_ratio_anon_votes_on_debates"] = 100
|
||||
debate = create(:debate)
|
||||
sign_in create(:user)
|
||||
|
||||
expect do
|
||||
post :create, xhr: true, params: { debate_id: debate.id, value: "yes" }
|
||||
end.to change { debate.reload.votes_for.size }.by(1)
|
||||
end
|
||||
|
||||
it "does not allow voting if user is not allowed" do
|
||||
Setting["max_ratio_anon_votes_on_debates"] = 0
|
||||
debate = create(:debate, cached_votes_total: 1000)
|
||||
sign_in create(:user)
|
||||
|
||||
expect do
|
||||
post :create, xhr: true, params: { debate_id: debate.id, value: "yes" }
|
||||
end.not_to change { debate.reload.votes_for.size }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE destroy" do
|
||||
let(:user) { create(:user) }
|
||||
let(:debate) { create(:debate) }
|
||||
let!(:vote) { create(:vote, votable: debate, voter: user) }
|
||||
before { sign_in user }
|
||||
|
||||
it "allows undoing a vote if user is allowed" do
|
||||
expect do
|
||||
delete :destroy, xhr: true, params: { debate_id: debate.id, id: vote }
|
||||
end.to change { debate.reload.votes_for.size }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -37,28 +37,6 @@ describe DebatesController do
|
||||
end
|
||||
end
|
||||
|
||||
describe "Vote with too many anonymous votes" do
|
||||
it "allows vote if user is allowed" do
|
||||
Setting["max_ratio_anon_votes_on_debates"] = 100
|
||||
debate = create(:debate)
|
||||
sign_in create(:user)
|
||||
|
||||
expect do
|
||||
post :vote, xhr: true, params: { id: debate.id, value: "yes" }
|
||||
end.to change { debate.reload.votes_for.size }.by(1)
|
||||
end
|
||||
|
||||
it "does not allow vote if user is not allowed" do
|
||||
Setting["max_ratio_anon_votes_on_debates"] = 0
|
||||
debate = create(:debate, cached_votes_total: 1000)
|
||||
sign_in create(:user)
|
||||
|
||||
expect do
|
||||
post :vote, xhr: true, params: { id: debate.id, value: "yes" }
|
||||
end.not_to change { debate.reload.votes_for.size }
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT mark_featured" do
|
||||
it "ignores query parameters" do
|
||||
debate = create(:debate)
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Legislation::Proposals::VotesController do
|
||||
let(:legislation_process) { create(:legislation_process) }
|
||||
let(:proposal) { create(:legislation_proposal, process: legislation_process) }
|
||||
|
||||
describe "POST create" do
|
||||
let(:vote_params) do
|
||||
{ process_id: legislation_process.id, legislation_proposal_id: proposal.id, value: "yes" }
|
||||
end
|
||||
|
||||
it "does not authorize unauthenticated users" do
|
||||
post :create, xhr: true, params: vote_params
|
||||
|
||||
expect(response).to be_unauthorized
|
||||
end
|
||||
|
||||
it "redirects unauthenticated users without JavaScript to the sign in page" do
|
||||
post :create, params: vote_params
|
||||
|
||||
expect(response).to redirect_to new_user_session_path
|
||||
end
|
||||
|
||||
it "allows vote if user is level_two_or_three_verified" do
|
||||
sign_in create(:user, :level_two)
|
||||
|
||||
expect do
|
||||
post :create, xhr: true, params: vote_params
|
||||
end.to change { proposal.reload.votes_for.size }.by(1)
|
||||
end
|
||||
|
||||
it "does not allow voting if user is not level_two_or_three_verified" do
|
||||
sign_in create(:user)
|
||||
|
||||
expect do
|
||||
post :create, xhr: true, params: vote_params
|
||||
end.not_to change { proposal.reload.votes_for.size }
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE destroy" do
|
||||
let(:user) { create(:user, :level_two) }
|
||||
let!(:vote) { create(:vote, votable: proposal, voter: user) }
|
||||
let(:vote_params) do
|
||||
{ process_id: legislation_process.id, legislation_proposal_id: proposal.id, id: vote }
|
||||
end
|
||||
|
||||
it "allows undoing a vote" do
|
||||
sign_in user
|
||||
|
||||
expect do
|
||||
delete :destroy, xhr: true, params: vote_params
|
||||
end.to change { proposal.reload.votes_for.size }.by(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -48,7 +48,6 @@ describe Abilities::Administrator do
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should be_able_to(:vote, debate) }
|
||||
|
||||
it { should be_able_to(:index, Proposal) }
|
||||
it { should be_able_to(:show, proposal) }
|
||||
|
||||
@@ -7,6 +7,7 @@ describe Abilities::Common do
|
||||
let(:geozone) { create(:geozone) }
|
||||
|
||||
let(:user) { create(:user, geozone: geozone) }
|
||||
let(:another_user) { create(:user) }
|
||||
|
||||
let(:debate) { create(:debate) }
|
||||
let(:comment) { create(:comment) }
|
||||
@@ -15,6 +16,7 @@ describe Abilities::Common do
|
||||
let(:own_comment) { create(:comment, author: user) }
|
||||
let(:own_proposal) { create(:proposal, author: user) }
|
||||
let(:own_legislation_proposal) { create(:legislation_proposal, author: user) }
|
||||
let(:legislation_proposal) { create(:legislation_proposal) }
|
||||
|
||||
let(:accepting_budget) { create(:budget, :accepting) }
|
||||
let(:reviewing_budget) { create(:budget, :reviewing) }
|
||||
@@ -73,7 +75,10 @@ describe Abilities::Common do
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should be_able_to(:vote, debate) }
|
||||
it { should be_able_to(:create, user.votes.build(votable: debate)) }
|
||||
it { should_not be_able_to(:create, another_user.votes.build(votable: debate)) }
|
||||
it { should be_able_to(:destroy, user.votes.build(votable: debate)) }
|
||||
it { should_not be_able_to(:destroy, another_user.votes.build(votable: debate)) }
|
||||
|
||||
it { should be_able_to(:show, user) }
|
||||
it { should be_able_to(:edit, user) }
|
||||
@@ -108,7 +113,10 @@ describe Abilities::Common do
|
||||
|
||||
describe "Comment" do
|
||||
it { should be_able_to(:create, Comment) }
|
||||
it { should be_able_to(:vote, Comment) }
|
||||
it { should be_able_to(:create, user.votes.build(votable: comment)) }
|
||||
it { should_not be_able_to(:create, another_user.votes.build(votable: comment)) }
|
||||
it { should be_able_to(:destroy, user.votes.build(votable: comment)) }
|
||||
it { should_not be_able_to(:destroy, another_user.votes.build(votable: comment)) }
|
||||
|
||||
it { should be_able_to(:hide, own_comment) }
|
||||
it { should_not be_able_to(:hide, comment) }
|
||||
@@ -137,20 +145,16 @@ describe Abilities::Common do
|
||||
end
|
||||
|
||||
describe "follows" do
|
||||
let(:other_user) { create(:user) }
|
||||
|
||||
it { should be_able_to(:create, build(:follow, :followed_proposal, user: user)) }
|
||||
it { should_not be_able_to(:create, build(:follow, :followed_proposal, user: other_user)) }
|
||||
it { should_not be_able_to(:create, build(:follow, :followed_proposal, user: another_user)) }
|
||||
|
||||
it { should be_able_to(:destroy, create(:follow, :followed_proposal, user: user)) }
|
||||
it { should_not be_able_to(:destroy, create(:follow, :followed_proposal, user: other_user)) }
|
||||
it { should_not be_able_to(:destroy, create(:follow, :followed_proposal, user: another_user)) }
|
||||
end
|
||||
|
||||
describe "other users" do
|
||||
let(:other_user) { create(:user) }
|
||||
|
||||
it { should be_able_to(:show, other_user) }
|
||||
it { should_not be_able_to(:edit, other_user) }
|
||||
it { should be_able_to(:show, another_user) }
|
||||
it { should_not be_able_to(:edit, another_user) }
|
||||
end
|
||||
|
||||
describe "editing debates" do
|
||||
@@ -182,6 +186,21 @@ describe Abilities::Common do
|
||||
it { should_not be_able_to(:edit, own_legislation_proposal) }
|
||||
it { should_not be_able_to(:update, own_legislation_proposal) }
|
||||
|
||||
describe "vote legislation proposal" do
|
||||
context "when user is not level_two_or_three_verified" do
|
||||
it { should_not be_able_to(:create, user.votes.build(votable: legislation_proposal)) }
|
||||
it { should_not be_able_to(:destroy, user.votes.build(votable: legislation_proposal)) }
|
||||
end
|
||||
|
||||
context "when user is level_two_or_three_verified" do
|
||||
before { user.update(level_two_verified_at: Date.current) }
|
||||
it { should be_able_to(:create, user.votes.build(votable: legislation_proposal)) }
|
||||
it { should_not be_able_to(:create, another_user.votes.build(votable: legislation_proposal)) }
|
||||
it { should be_able_to(:destroy, user.votes.build(votable: legislation_proposal)) }
|
||||
it { should_not be_able_to(:destroy, another_user.votes.build(votable: legislation_proposal)) }
|
||||
end
|
||||
end
|
||||
|
||||
describe "proposals dashboard" do
|
||||
it { should be_able_to(:dashboard, own_proposal) }
|
||||
it { should_not be_able_to(:dashboard, proposal) }
|
||||
|
||||
@@ -25,7 +25,6 @@ describe Abilities::Moderator do
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should be_able_to(:vote, debate) }
|
||||
|
||||
it { should be_able_to(:index, Proposal) }
|
||||
it { should be_able_to(:show, proposal) }
|
||||
|
||||
@@ -8,20 +8,23 @@ describe "Abilities::Organization" do
|
||||
let(:organization) { create(:organization) }
|
||||
let(:debate) { create(:debate) }
|
||||
let(:proposal) { create(:proposal) }
|
||||
let(:comment) { create(:comment) }
|
||||
|
||||
it { should be_able_to(:show, user) }
|
||||
it { should be_able_to(:edit, user) }
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should_not be_able_to(:vote, debate) }
|
||||
it { should_not be_able_to(:create, user.votes.build(votable: debate)) }
|
||||
it { should_not be_able_to(:destroy, user.votes.build(votable: debate)) }
|
||||
|
||||
it { should be_able_to(:index, Proposal) }
|
||||
it { should be_able_to(:show, proposal) }
|
||||
it { should_not be_able_to(:vote, Proposal) }
|
||||
|
||||
it { should be_able_to(:create, Comment) }
|
||||
it { should_not be_able_to(:vote, Comment) }
|
||||
it { should_not be_able_to(:create, user.votes.build(votable: comment)) }
|
||||
it { should_not be_able_to(:destroy, user.votes.build(votable: comment)) }
|
||||
|
||||
it { should_not be_able_to(:read, SDG::Target) }
|
||||
|
||||
|
||||
@@ -16,6 +16,26 @@ describe "Polymorphic routes" do
|
||||
expect(polymorphic_path(proposal)).to eq legislation_process_proposal_path(process, proposal)
|
||||
end
|
||||
|
||||
it "routes legislation proposals vote" do
|
||||
process = create(:legislation_process)
|
||||
proposal = create(:legislation_proposal, process: process)
|
||||
path = polymorphic_path(Vote.new(votable: proposal), value: true)
|
||||
|
||||
expect(path).to eq legislation_process_legislation_proposal_votes_path(process, proposal, value: true)
|
||||
end
|
||||
|
||||
it "routes legislation proposals remove vote" do
|
||||
process = create(:legislation_process)
|
||||
proposal = create(:legislation_proposal, process: process)
|
||||
vote = create(:vote, votable: proposal)
|
||||
path = polymorphic_path(vote, value: true)
|
||||
|
||||
expect(path).to eq legislation_process_legislation_proposal_vote_path(process,
|
||||
proposal,
|
||||
vote,
|
||||
value: true)
|
||||
end
|
||||
|
||||
it "routes legislation questions" do
|
||||
process = create(:legislation_process)
|
||||
question = create(:legislation_question, process: process)
|
||||
|
||||
@@ -578,7 +578,7 @@ describe "Commenting Budget::Investments" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit budget_investment_path(budget, investment)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -591,14 +591,14 @@ describe "Commenting Budget::Investments" do
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -614,7 +614,7 @@ describe "Commenting debates" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit debate_path(debate)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -626,14 +626,14 @@ describe "Commenting debates" do
|
||||
click_button "I agree"
|
||||
within(".in-favor") do
|
||||
expect(page).not_to have_content "2"
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -550,7 +550,7 @@ describe "Commenting legislation questions" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit polymorphic_path(annotation)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -562,14 +562,14 @@ describe "Commenting legislation questions" do
|
||||
click_button "I agree"
|
||||
within(".in-favor") do
|
||||
expect(page).not_to have_content "2"
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -534,7 +534,7 @@ describe "Commenting legislation questions" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit legislation_process_question_path(question.process, question)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -546,14 +546,14 @@ describe "Commenting legislation questions" do
|
||||
click_button "I agree"
|
||||
within(".in-favor") do
|
||||
expect(page).not_to have_content "2"
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -495,7 +495,7 @@ describe "Commenting polls" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit poll_path(poll)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -508,14 +508,14 @@ describe "Commenting polls" do
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -500,7 +500,7 @@ describe "Commenting proposals" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit proposal_path(proposal)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -513,14 +513,14 @@ describe "Commenting proposals" do
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -547,7 +547,7 @@ describe "Commenting topics from proposals" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit community_topic_path(proposal.community, topic)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -560,14 +560,14 @@ describe "Commenting topics from proposals" do
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1060,7 +1060,7 @@ describe "Commenting topics from budget investments" do
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit community_topic_path(investment.community, topic)
|
||||
|
||||
within("#comment_#{comment.id}_votes") do
|
||||
@@ -1073,14 +1073,14 @@ describe "Commenting topics from budget investments" do
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "1"
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).to have_content "No votes"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -19,37 +19,31 @@ describe "Votes" do
|
||||
within("#debates") do
|
||||
within("#debate_#{debate1.id}_votes") do
|
||||
within(".in-favor") do
|
||||
expect(page).to have_button class: "voted"
|
||||
expect(page).not_to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_button class: "no-voted"
|
||||
expect(page).not_to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
end
|
||||
|
||||
within("#debate_#{debate2.id}_votes") do
|
||||
within(".in-favor") do
|
||||
expect(page).not_to have_button class: "voted"
|
||||
expect(page).not_to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).not_to have_button class: "no-voted"
|
||||
expect(page).not_to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
end
|
||||
|
||||
within("#debate_#{debate3.id}_votes") do
|
||||
within(".in-favor") do
|
||||
expect(page).to have_button class: "no-voted"
|
||||
expect(page).not_to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_button class: "voted"
|
||||
expect(page).not_to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -63,56 +57,70 @@ describe "Votes" do
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).not_to have_button class: "voted"
|
||||
expect(page).not_to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).not_to have_button class: "voted"
|
||||
expect(page).not_to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Update" do
|
||||
scenario "Create and update from debate show" do
|
||||
visit debate_path(create(:debate))
|
||||
|
||||
expect(page).to have_content "No votes"
|
||||
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
|
||||
click_button "I disagree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
|
||||
scenario "Trying to vote multiple times" do
|
||||
scenario "Allow undoing votes" do
|
||||
visit debate_path(create(:debate))
|
||||
|
||||
click_button "I agree"
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).not_to have_content "No votes"
|
||||
|
||||
click_button "I agree"
|
||||
|
||||
expect(page).to have_content "No votes"
|
||||
expect(page).not_to have_content "2 votes"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -127,33 +135,15 @@ describe "Votes" do
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "50%"
|
||||
expect(page).to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "50%"
|
||||
expect(page).to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Create from debate show" do
|
||||
visit debate_path(create(:debate))
|
||||
|
||||
click_button "I agree"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_button class: "voted"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_button class: "no-voted"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
|
||||
scenario "Create in index" do
|
||||
create(:debate)
|
||||
visit debates_path
|
||||
@@ -163,12 +153,12 @@ describe "Votes" do
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_button class: "voted"
|
||||
expect(page).to have_css "button[aria-pressed='true']"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_button class: "no-voted"
|
||||
expect(page).to have_css "button[aria-pressed='false']"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
@@ -354,4 +344,31 @@ describe "Votes" do
|
||||
expect(page).not_to have_button "Support", disabled: :all
|
||||
end
|
||||
end
|
||||
|
||||
describe "Legislation Proposals" do
|
||||
let(:proposal) { create(:legislation_proposal) }
|
||||
|
||||
scenario "Allow undoing votes" do
|
||||
login_as verified
|
||||
visit legislation_process_proposal_path(proposal.process, proposal)
|
||||
|
||||
click_button "I agree"
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
expect(page).not_to have_content "No votes"
|
||||
|
||||
click_button "I agree"
|
||||
|
||||
expect(page).to have_content "No votes"
|
||||
expect(page).not_to have_content "2 votes"
|
||||
|
||||
within(".in-favor") do
|
||||
expect(page).to have_content "0%"
|
||||
end
|
||||
|
||||
within(".against") do
|
||||
expect(page).to have_content "0%"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user