Merge pull request #4764 from consul/participation_not_allowed

Make "participation not allowed" message accessible
This commit is contained in:
Javi Martín
2022-02-23 17:47:43 +01:00
committed by GitHub
44 changed files with 298 additions and 317 deletions

View File

@@ -65,7 +65,7 @@
//= require jquery.amsify.suggestags //= require jquery.amsify.suggestags
//= require tags //= require tags
//= require users //= require users
//= require votes //= require participation_not_allowed
//= require advanced_search //= require advanced_search
//= require registration_form //= require registration_form
//= require suggest //= require suggest
@@ -122,7 +122,7 @@ var initialize_modules = function() {
App.Questions.initialize(); App.Questions.initialize();
App.Comments.initialize(); App.Comments.initialize();
App.Users.initialize(); App.Users.initialize();
App.Votes.initialize(); App.ParticipationNotAllowed.initialize();
App.Tags.initialize(); App.Tags.initialize();
App.FoundationExtras.initialize(); App.FoundationExtras.initialize();
App.LocationChanger.initialize(); App.LocationChanger.initialize();

View File

@@ -0,0 +1,29 @@
(function() {
"use strict";
App.ParticipationNotAllowed = {
not_allowed: function(votes_selector) {
var buttons_selector = votes_selector + " [type='submit']";
$("body").on("click", buttons_selector, function(event) {
var votes = $(event.target).closest(votes_selector);
var not_allowed = $("div.participation-not-allowed", votes);
if (not_allowed.length > 0) {
event.preventDefault();
not_allowed.show().focus();
if (votes_selector === "div.votes") {
$("button", votes).prop("disabled", true);
} else {
$(event.target).closest("form").remove();
}
}
});
},
initialize: function() {
App.ParticipationNotAllowed.not_allowed("div.votes");
App.ParticipationNotAllowed.not_allowed("div.supports");
}
};
}).call(this);

View File

@@ -1,21 +0,0 @@
(function() {
"use strict";
App.Votes = {
hoverize: function(votes) {
$(document).on({
"mouseenter focus": function() {
$("div.participation-not-allowed", this).show();
},
mouseleave: function() {
$("div.participation-not-allowed", this).hide();
}
}, votes);
},
initialize: function() {
App.Votes.hoverize("div.votes");
App.Votes.hoverize("div.supports");
App.Votes.hoverize("div.debate-questions");
App.Votes.hoverize("div.comment-footer");
}
};
}).call(this);

View File

@@ -23,6 +23,7 @@
padding: rem-calc(3) rem-calc(6) rem-calc(6); padding: rem-calc(3) rem-calc(6) rem-calc(6);
position: relative; position: relative;
&:not([disabled]) {
&:hover, &:hover,
&:active { &:active {
color: #fff; color: #fff;
@@ -30,26 +31,31 @@
opacity: 1 !important; opacity: 1 !important;
} }
} }
}
.in-favor button { .in-favor button {
@include has-fa-icon(thumbs-up, solid); @include has-fa-icon(thumbs-up, solid);
&:not([disabled]) {
&:hover, &:hover,
&:active { &:active {
background: $like; background: $like;
border: 2px solid $like; border: 2px solid $like;
} }
} }
}
.against button { .against button {
@include has-fa-icon(thumbs-down, solid); @include has-fa-icon(thumbs-down, solid);
&:not([disabled]) {
&:hover, &:hover,
&:active { &:active {
background: $unlike; background: $unlike;
border: 2px solid $unlike; border: 2px solid $unlike;
} }
} }
}
.like, .like,
.unlike { .unlike {

View File

@@ -630,21 +630,6 @@
.comments-wrapper { .comments-wrapper {
position: relative; position: relative;
.participation-not-allowed {
padding: rem-calc(20) rem-calc(8);
}
}
.comment-footer {
position: relative;
.participation-not-allowed {
font-size: rem-calc(14);
height: rem-calc(50);
padding: $line-height / 2;
top: -18px;
}
} }
.comment-input { .comment-input {

View File

@@ -98,15 +98,16 @@
.participation-not-allowed { .participation-not-allowed {
background: $warning-bg; background: $warning-bg;
color: $color-warning; color: $color-warning;
left: 0; display: none;
line-height: $line-height; line-height: $line-height;
min-height: 100%;
padding: $line-height / 2; padding: $line-height / 2;
position: absolute;
text-align: center; text-align: center;
top: 0;
width: 100%; width: 100%;
z-index: 2;
&,
p {
font-size: $small-font-size;
}
p { p {
color: inherit !important; color: inherit !important;
@@ -121,12 +122,6 @@
} }
} }
.reply .participation-not-allowed {
padding-right: $line-height / 2;
padding-top: $line-height / 6;
text-align: right;
}
// 02. New participation // 02. New participation
// --------------------- // ---------------------
@@ -327,6 +322,10 @@
} }
} }
.debate-questions .debate-questions .participation-not-allowed {
display: block;
}
.bullet { .bullet {
color: $text; color: $text;
} }
@@ -664,10 +663,6 @@
font-size: $base-font-size; font-size: $base-font-size;
font-weight: bold; font-weight: bold;
&:disabled {
opacity: 1;
}
&:hover { &:hover {
background: $budget-hover; background: $budget-hover;
color: #fff; color: #fff;
@@ -955,7 +950,6 @@
.participation-not-allowed { .participation-not-allowed {
background: $featured; background: $featured;
font-size: $small-font-size;
padding-top: 0; padding-top: 0;
a { a {

View File

@@ -32,7 +32,6 @@
title: t("budgets.investments.investment.support_title"), title: t("budgets.investments.investment.support_title"),
method: :post, method: :post,
remote: true, remote: true,
disabled: reason.present?,
"aria-label": vote_aria_label do %> "aria-label": vote_aria_label do %>
<%= t("budgets.investments.investment.add") %> <%= t("budgets.investments.investment.add") %>
<% end %> <% end %>
@@ -40,19 +39,5 @@
</div> </div>
<% end %> <% end %>
<% if reason.present? && !voted? %> <%= render Shared::ParticipationNotAllowedComponent.new(investment, cannot_vote_text: cannot_vote_text) %>
<div tabindex="0">
<div class="participation-not-allowed" style="display:none">
<p>
<small>
<%= sanitize(t("budgets.ballots.reasons_for_not_balloting.#{reason}",
verify_account: link_to_verify_account, signin: link_to_signin,
signup: link_to_signup, my_heading: link_to_my_heading,
change_ballot: link_to_change_ballot,
heading_link: heading_link(assigned_heading, budget))) %>
</small>
</p>
</div>
</div>
<% end %>
</div> </div>

View File

@@ -1,7 +1,6 @@
class Budgets::Investments::BallotComponent < ApplicationComponent class Budgets::Investments::BallotComponent < ApplicationComponent
attr_reader :investment, :investment_ids, :ballot, :assigned_heading attr_reader :investment, :investment_ids, :ballot, :assigned_heading
delegate :current_user, :heading_link, :link_to_signin, :link_to_signup, delegate :current_user, :heading_link, :link_to_verify_account, to: :helpers
:link_to_verify_account, to: :helpers
def initialize(investment:, investment_ids:, ballot:, assigned_heading:) def initialize(investment:, investment_ids:, ballot:, assigned_heading:)
@investment = investment @investment = investment
@@ -42,4 +41,14 @@ class Budgets::Investments::BallotComponent < ApplicationComponent
link_to(t("budgets.ballots.reasons_for_not_balloting.change_ballot"), link_to(t("budgets.ballots.reasons_for_not_balloting.change_ballot"),
budget_ballot_path(budget)) budget_ballot_path(budget))
end end
def cannot_vote_text
if reason.present? && !voted?
t("budgets.ballots.reasons_for_not_balloting.#{reason}",
verify_account: link_to_verify_account,
my_heading: link_to_my_heading,
change_ballot: link_to_change_ballot,
heading_link: heading_link(assigned_heading, budget))
end
end
end end

View File

@@ -28,29 +28,12 @@
method: "post", method: "post",
remote: !display_support_alert?, remote: !display_support_alert?,
data: ({ confirm: confirm_vote_message } if display_support_alert?), data: ({ confirm: confirm_vote_message } if display_support_alert?),
disabled: !current_user,
"aria-label": support_aria_label %> "aria-label": support_aria_label %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<% if reason.present? && !user_voted_for? %> <%= render Shared::ParticipationNotAllowedComponent.new(investment, cannot_vote_text: cannot_vote_text) %>
<div tabindex="0">
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<small>
<%= sanitize(t("votes.budget_investments.#{reason}",
count: investment.group.max_votable_headings,
verify_account: link_to_verify_account,
signin: link_to_signin,
signup: link_to_signup,
supported_headings: (current_user && current_user.headings_voted_within_group(investment.group).map(&:name).sort.to_sentence)
)) %>
</small>
</p>
</div>
</div>
<% end %>
<% if user_voted_for? && setting["twitter_handle"] %> <% if user_voted_for? && setting["twitter_handle"] %>
<div class="share-supported"> <div class="share-supported">

View File

@@ -1,7 +1,6 @@
class Budgets::Investments::VotesComponent < ApplicationComponent class Budgets::Investments::VotesComponent < ApplicationComponent
attr_reader :investment attr_reader :investment
delegate :namespace, :current_user, :image_absolute_url, delegate :namespace, :current_user, :image_absolute_url, :link_to_verify_account, to: :helpers
:link_to_verify_account, :link_to_signin, :link_to_signup, to: :helpers
def initialize(investment) def initialize(investment)
@investment = investment @investment = investment
@@ -59,4 +58,13 @@ class Budgets::Investments::VotesComponent < ApplicationComponent
def remove_support_aria_label def remove_support_aria_label
t("budgets.investments.votes.remove_support_label", investment: investment.title) t("budgets.investments.votes.remove_support_label", investment: investment.title)
end end
def cannot_vote_text
if reason.present? && !user_voted_for?
t("votes.budget_investments.#{reason}",
count: investment.group.max_votable_headings,
verify_account: link_to_verify_account,
supported_headings: (current_user && current_user.headings_voted_within_group(investment.group).map(&:name).sort.to_sentence))
end
end
end end

View File

@@ -5,9 +5,8 @@
<span class="in-favor"> <span class="in-favor">
<%= button_to vote_comment_path(comment, value: "yes"), <%= button_to vote_comment_path(comment, value: "yes"),
method: "post", method: "post",
remote: true, remote: can?(:vote, comment),
title: t("votes.agree"), title: t("votes.agree") do %>
disabled: !can?(:vote, comment) do %>
<span class="show-for-sr"><%= t("votes.agree") %></span> <span class="show-for-sr"><%= t("votes.agree") %></span>
<% end %> <% end %>
<%= comment.total_likes %> <%= comment.total_likes %>
@@ -16,19 +15,10 @@
<span class="against"> <span class="against">
<%= button_to vote_comment_path(comment, value: "no"), <%= button_to vote_comment_path(comment, value: "no"),
method: "post", method: "post",
remote: true, remote: can?(:vote, comment),
title: t("votes.disagree"), title: t("votes.disagree") do %>
disabled: !can?(:vote, comment) do %>
<span class="show-for-sr"><%= t("votes.disagree") %></span> <span class="show-for-sr"><%= t("votes.disagree") %></span>
<% end %> <% end %>
<%= comment.total_dislikes %> <%= comment.total_dislikes %>
</span> </span>
<% unless current_user %>
<div tabindex="0">
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<%= sanitize(t("votes.comment_unauthenticated", signin: link_to_signin, signup: link_to_signup)) %>
</div>
</div>
<% end %>
</div> </div>

View File

@@ -1,6 +1,6 @@
class Comments::VotesComponent < ApplicationComponent class Comments::VotesComponent < ApplicationComponent
attr_reader :comment attr_reader :comment
delegate :current_user, :can?, :link_to_signin, :link_to_signup, to: :helpers delegate :can?, to: :helpers
def initialize(comment) def initialize(comment)
@comment = comment @comment = comment

View File

@@ -1,25 +1,9 @@
<div class="votes"> <div class="votes">
<%= render Shared::InFavorAgainstComponent.new(debate) %> <%= render Shared::InFavorAgainstComponent.new(debate) %>
<%= render Shared::ParticipationNotAllowedComponent.new(debate, cannot_vote_text: cannot_vote_text) %>
<span class="total-votes"> <span class="total-votes">
<%= t("debates.debate.votes", count: debate.votes_score) %> <%= t("debates.debate.votes", count: debate.votes_score) %>
</span> </span>
<% if !current_user %>
<div tabindex="0">
<%= render "shared/login_to_vote" %>
</div>
<% elsif organization? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif !can_vote? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<%= sanitize(t("votes.anonymous", verify_account: link_to_verify_account)) %>
</p>
</div>
<% end %>
</div> </div>

View File

@@ -12,7 +12,7 @@ class Debates::VotesComponent < ApplicationComponent
debate.votable_by?(current_user) debate.votable_by?(current_user)
end end
def organization? def cannot_vote_text
current_user&.organization? t("votes.anonymous", verify_account: link_to_verify_account) unless can_vote?
end end
end end

View File

@@ -3,29 +3,12 @@
<%= render Shared::InFavorAgainstComponent.new(proposal) %> <%= render Shared::InFavorAgainstComponent.new(proposal) %>
<% end %> <% end %>
<%= render Shared::ParticipationNotAllowedComponent.new(proposal, cannot_vote_text: cannot_vote_text) %>
<span class="total-votes"> <span class="total-votes">
<%= t("proposals.proposal.votes", count: proposal.votes_score) %> <%= t("proposals.proposal.votes", count: proposal.votes_score) %>
</span> </span>
<% if !current_user %>
<div tabindex="0">
<%= render "shared/login_to_vote" %>
</div>
<% elsif organization? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif !can_vote? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<%= sanitize(t("legislation.proposals.not_verified",
verify_account: link_to_verify_account)) %>
</p>
</div>
<% end %>
<% if current_user&.voted_as_when_voted_for(proposal) && setting["twitter_handle"] %> <% if current_user&.voted_as_when_voted_for(proposal) && setting["twitter_handle"] %>
<div class="share-supported"> <div class="share-supported">
<%= render "shared/social_share", <%= render "shared/social_share",

View File

@@ -12,7 +12,7 @@ class Legislation::Proposals::VotesComponent < ApplicationComponent
proposal.votable_by?(current_user) proposal.votable_by?(current_user)
end end
def organization? def cannot_vote_text
current_user&.organization? t("legislation.proposals.not_verified", verify_account: link_to_verify_account) unless can_vote?
end end
end end

View File

@@ -12,32 +12,13 @@
title: t("proposals.proposal.support_title"), title: t("proposals.proposal.support_title"),
method: "post", method: "post",
remote: true, remote: true,
disabled: !can_vote?,
"aria-label": support_aria_label do %> "aria-label": support_aria_label do %>
<%= t("proposals.proposal.support") %> <%= t("proposals.proposal.support") %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<% if !current_user %> <%= render Shared::ParticipationNotAllowedComponent.new(proposal, cannot_vote_text: cannot_vote_text) %>
<div tabindex="0">
<%= render "shared/login_to_vote" %>
</div>
<% elsif organization? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<%= t("votes.organizations") %>
</p>
</div>
<% elsif !can_vote? %>
<div tabindex="0">
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<p>
<%= sanitize(t("votes.verified_only", verify_account: link_to_verify_account)) %>
</p>
</div>
</div>
<% end %>
<% if voted? && setting["twitter_handle"] %> <% if voted? && setting["twitter_handle"] %>
<div class="share-supported"> <div class="share-supported">

View File

@@ -25,7 +25,7 @@ class Proposals::VotesComponent < ApplicationComponent
t("proposals.proposal.support_label", proposal: proposal.title) t("proposals.proposal.support_label", proposal: proposal.title)
end end
def organization? def cannot_vote_text
current_user&.organization? t("votes.verified_only", verify_account: link_to_verify_account) unless can_vote?
end end
end end

View File

@@ -5,8 +5,7 @@
title: t("votes.agree"), title: t("votes.agree"),
"aria-label": agree_aria_label, "aria-label": agree_aria_label,
method: "post", method: "post",
remote: true, remote: true do %>
disabled: !current_user do %>
<span class="show-for-sr"><%= t("votes.agree") %></span> <span class="show-for-sr"><%= t("votes.agree") %></span>
<% end %> <% end %>
<span class="percentage"><%= votes_percentage("likes", votable) %></span> <span class="percentage"><%= votes_percentage("likes", votable) %></span>
@@ -18,8 +17,7 @@
title: t("votes.disagree"), title: t("votes.disagree"),
"aria-label": disagree_aria_label, "aria-label": disagree_aria_label,
method: "post", method: "post",
remote: true, remote: true do %>
disabled: !current_user do %>
<span class="show-for-sr"><%= t("votes.disagree") %></span> <span class="show-for-sr"><%= t("votes.disagree") %></span>
<% end %> <% end %>
<span class="percentage"><%= votes_percentage("dislikes", votable) %></span> <span class="percentage"><%= votes_percentage("dislikes", votable) %></span>

View File

@@ -0,0 +1,3 @@
<div class="participation-not-allowed" tabindex="-1">
<%= body %>
</div>

View File

@@ -0,0 +1,30 @@
class Shared::ParticipationNotAllowedComponent < ApplicationComponent
attr_reader :votable, :cannot_vote_text
delegate :current_user, :link_to_signin, :link_to_signup, to: :helpers
def initialize(votable, cannot_vote_text:)
@votable = votable
@cannot_vote_text = cannot_vote_text
end
def render?
body.present?
end
private
def body
@body ||=
if !current_user
sanitize(t("users.login_to_continue", signin: link_to_signin, signup: link_to_signup))
elsif organization?
tag.p t("votes.organizations")
elsif cannot_vote_text.present?
tag.p sanitize(cannot_vote_text)
end
end
def organization?
current_user&.organization?
end
end

View File

@@ -1,5 +1,5 @@
class CommentsController < ApplicationController class CommentsController < ApplicationController
before_action :authenticate_user!, only: [:create, :hide] before_action :authenticate_user!, only: [:create, :hide, :vote]
before_action :load_commentable, only: :create before_action :load_commentable, only: :create
before_action :verify_resident_for_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, :vote]

View File

@@ -16,12 +16,9 @@
<% end %> <% end %>
<% if @process.allegations_phase.open? %> <% if @process.allegations_phase.open? %>
<% if user_signed_in? %>
<a class="button publish-comment" href="#"><strong><%= t("legislation.annotations.comments.publish_comment") %></strong></a> <a class="button publish-comment" href="#"><strong><%= t("legislation.annotations.comments.publish_comment") %></strong></a>
&nbsp; &nbsp;
<% end %>
<% if @process.allegations_phase.open? %>
<% if user_signed_in? %>
<% css_id = parent_or_commentable_dom_id(nil, annotation) %> <% css_id = parent_or_commentable_dom_id(nil, annotation) %>
<div id="js-comment-form-annotation-<%= annotation.id %>" style="display:none" class="comment-form js-comment-form-annotation"> <div id="js-comment-form-annotation-<%= annotation.id %>" style="display:none" class="comment-form js-comment-form-annotation">
<%= form_for @comment, url: legislation_process_draft_version_annotation_new_comment_path(annotation.draft_version.process, annotation.draft_version, annotation), remote: true do |f| %> <%= form_for @comment, url: legislation_process_draft_version_annotation_new_comment_path(annotation.draft_version.process, annotation.draft_version, annotation), remote: true do |f| %>
@@ -34,14 +31,7 @@
<% end %> <% end %>
</div> </div>
<% else %> <% else %>
<%= render "shared/login_to_comment" %>
<div>
<div class="participation-not-allowed" style="display: none;" aria-hidden="false">
<%= sanitize(t("users.login_to_comment",
signin: link_to_signin, signup: link_to_signup)) %>
</div>
</div>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

View File

@@ -1,5 +1,5 @@
<% if question.question_options.any? %> <% if question.question_options.any? %>
<% if process.debate_phase.open? && !answer.persisted? %> <% if process.debate_phase.open? && !answer.persisted? && can?(:create, Legislation::Answer) %>
<%= form_for answer, url: legislation_process_question_answers_path(process, question, answer), remote: true, html: { class: "controls-stacked" } do |f| %> <%= form_for answer, url: legislation_process_question_answers_path(process, question, answer), remote: true, html: { class: "controls-stacked" } do |f| %>
<% question.question_options.each do |question_option| %> <% question.question_options.each do |question_option| %>
@@ -25,4 +25,6 @@
</form> </form>
<% end %> <% end %>
<%= render "participation_not_allowed" %>
<% end %> <% end %>

View File

@@ -1,23 +1,23 @@
<% if user_signed_in? && current_user.organization? %> <% if user_signed_in? && current_user.organization? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false"> <div class="participation-not-allowed">
<p> <p>
<%= t("legislation.questions.participation.organizations") %> <%= t("legislation.questions.participation.organizations") %>
</p> </p>
</div> </div>
<% elsif user_signed_in? && current_user.unverified? %> <% elsif user_signed_in? && current_user.unverified? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false"> <div class="participation-not-allowed">
<p> <p>
<%= sanitize(t("legislation.questions.participation.verified_only", <%= sanitize(t("legislation.questions.participation.verified_only",
verify_account: link_to_verify_account)) %> verify_account: link_to_verify_account)) %>
</p> </p>
</div> </div>
<% elsif !user_signed_in? %> <% elsif !user_signed_in? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false"> <div class="participation-not-allowed">
<%= sanitize(t("legislation.questions.participation.unauthenticated", <%= sanitize(t("legislation.questions.participation.unauthenticated",
signin: link_to_signin, signup: link_to_signup)) %> signin: link_to_signin, signup: link_to_signup)) %>
</div> </div>
<% elsif !@process.debate_phase.open? %> <% elsif !@process.debate_phase.open? %>
<div class="participation-not-allowed" style="display:none" aria-hidden="false"> <div class="participation-not-allowed">
<%= t("legislation.questions.participation.debate_phase_not_open") %> <%= t("legislation.questions.participation.debate_phase_not_open") %>
</div> </div>
<% end %> <% end %>

View File

@@ -31,7 +31,6 @@
<h3 class="quiz-question"><%= @question.title %></h3> <h3 class="quiz-question"><%= @question.title %></h3>
<div class="debate-questions" id="legislation-answer-form"> <div class="debate-questions" id="legislation-answer-form">
<%= render "answer_form", process: @process, question: @question, answer: @answer %> <%= render "answer_form", process: @process, question: @question, answer: @answer %>
<%= render "participation_not_allowed" %>
</div> </div>
</div> </div>

View File

@@ -1,3 +0,0 @@
<div class="participation-not-allowed" style="display:none" aria-hidden="false">
<%= sanitize(t("users.login_to_continue", signin: link_to_signin, signup: link_to_signup)) %>
</div>

View File

@@ -31,9 +31,7 @@ en:
voted_info_2: "But you can change your vote at any time until this phase is closed." voted_info_2: "But you can change your vote at any time until this phase is closed."
zero: You have not voted any investment project. zero: You have not voted any investment project.
reasons_for_not_balloting: reasons_for_not_balloting:
not_logged_in: You must %{signin} or %{signup} to continue.
not_verified: Only verified users can vote on investments; %{verify_account}. not_verified: Only verified users can vote on investments; %{verify_account}.
organization: Organizations are not permitted to vote
not_selected: Unselected investment projects can not be supported not_selected: Unselected investment projects can not be supported
not_enough_money: "You have already assigned the available budget.<br><small>Remember you can %{change_ballot} at any time</small>" not_enough_money: "You have already assigned the available budget.<br><small>Remember you can %{change_ballot} at any time</small>"
no_ballots_allowed: Selecting phase is closed no_ballots_allowed: Selecting phase is closed

View File

@@ -849,16 +849,13 @@ en:
agree: I agree agree: I agree
agree_label: "I agree with %{title}" agree_label: "I agree with %{title}"
anonymous: Too many anonymous votes to admit vote %{verify_account}. anonymous: Too many anonymous votes to admit vote %{verify_account}.
comment_unauthenticated: You must %{signin} or %{signup} to vote.
disagree: I disagree disagree: I disagree
disagree_label: "I don't agree with %{title}" disagree_label: "I don't agree with %{title}"
organizations: Organizations are not permitted to vote organizations: Organizations are not permitted to vote
supports: Supports supports: Supports
verified_only: Only verified users can vote on proposals; %{verify_account}. verified_only: Only verified users can vote on proposals; %{verify_account}.
budget_investments: budget_investments:
not_logged_in: You must %{signin} or %{signup} to continue.
not_verified: Only verified users can vote on investment projects; %{verify_account}. not_verified: Only verified users can vote on investment projects; %{verify_account}.
organization: Organizations are not permitted to vote
unfeasible: Unfeasible investment projects can not be supported unfeasible: Unfeasible investment projects can not be supported
not_voting_allowed: Voting phase is closed not_voting_allowed: Voting phase is closed
different_heading_assigned: different_heading_assigned:

View File

@@ -31,9 +31,7 @@ es:
voted_info_2: "Pero puedes cambiarlos en cualquier momento hasta el cierre de esta fase." voted_info_2: "Pero puedes cambiarlos en cualquier momento hasta el cierre de esta fase."
zero: Todavía no has votado ningún proyecto de gasto. zero: Todavía no has votado ningún proyecto de gasto.
reasons_for_not_balloting: reasons_for_not_balloting:
not_logged_in: Necesitas %{signin} o %{signup} para continuar.
not_verified: Los proyectos de gasto sólo pueden ser apoyados por usuarios verificados, %{verify_account}. not_verified: Los proyectos de gasto sólo pueden ser apoyados por usuarios verificados, %{verify_account}.
organization: Las organizaciones no pueden votar.
not_selected: No se pueden votar proyectos inviables. not_selected: No se pueden votar proyectos inviables.
not_enough_money: "Ya has asignado el presupuesto disponible.<br><small>Recuerda que puedes %{change_ballot} en cualquier momento</small>" not_enough_money: "Ya has asignado el presupuesto disponible.<br><small>Recuerda que puedes %{change_ballot} en cualquier momento</small>"
no_ballots_allowed: El periodo de votación está cerrado. no_ballots_allowed: El periodo de votación está cerrado.

View File

@@ -849,16 +849,13 @@ es:
agree: Estoy de acuerdo agree: Estoy de acuerdo
agree_label: "Estoy de acuerdo con %{title}" agree_label: "Estoy de acuerdo con %{title}"
anonymous: Demasiados votos anónimos, para poder votar %{verify_account}. anonymous: Demasiados votos anónimos, para poder votar %{verify_account}.
comment_unauthenticated: Necesitas %{signin} o %{signup} para poder votar.
disagree: No estoy de acuerdo disagree: No estoy de acuerdo
disagree_label: "No estoy de acuerdo con %{title}" disagree_label: "No estoy de acuerdo con %{title}"
organizations: Las organizaciones no pueden votar. organizations: Las organizaciones no pueden votar.
supports: Apoyos supports: Apoyos
verified_only: Las propuestas sólo pueden ser votadas por usuarios verificados, %{verify_account}. verified_only: Las propuestas sólo pueden ser votadas por usuarios verificados, %{verify_account}.
budget_investments: budget_investments:
not_logged_in: Necesitas %{signin} o %{signup} para continuar.
not_verified: Los proyectos de gasto sólo pueden ser apoyadas por usuarios verificados, %{verify_account}. not_verified: Los proyectos de gasto sólo pueden ser apoyadas por usuarios verificados, %{verify_account}.
organization: Las organizaciones no pueden votar.
unfeasible: No se pueden votar propuestas inviables. unfeasible: No se pueden votar propuestas inviables.
not_voting_allowed: El periodo de votación está cerrado. not_voting_allowed: El periodo de votación está cerrado.
different_heading_assigned: different_heading_assigned:

View File

@@ -18,7 +18,7 @@ describe Budgets::Investments::BallotComponent do
render_inline component render_inline component
expect(page).to have_button "Vote", disabled: true expect(page).to have_button "Vote"
expect(page).to have_content "Only verified users can vote on investments; verify your account." expect(page).to have_content "Only verified users can vote on investments; verify your account."
end end

View File

@@ -18,11 +18,12 @@ describe Budgets::Investments::VotesComponent do
expect(page).to have_button "Support Renovate sidewalks in Main Street" expect(page).to have_button "Support Renovate sidewalks in Main Street"
end end
it "disables the button to support the investment to unidentified users" do it "renders the support button and a reminder to sign in to unidentified users" do
render_inline component render_inline component
expect(page).to have_button count: 1, disabled: :all expect(page).to have_button count: 1, disabled: :all
expect(page).to have_button "Support", disabled: true expect(page).to have_button "Support"
expect(page).to have_content "You must sign in or sign up to continue."
end end
describe "button to remove support" do describe "button to remove support" do

View File

@@ -5,11 +5,11 @@ describe Debates::VotesComponent do
let(:component) { Debates::VotesComponent.new(debate) } let(:component) { Debates::VotesComponent.new(debate) }
describe "Agree and disagree buttons" do describe "Agree and disagree buttons" do
it "is disabled to anonymous users" do it "is shown to anonymous users alongside a reminder to sign in" do
render_inline component render_inline component
expect(page).to have_button "I agree", disabled: true expect(page).to have_button "I agree"
expect(page).to have_button "I disagree", disabled: true expect(page).to have_button "I disagree"
expect(page).to have_content "You must sign in or sign up to continue." expect(page).to have_content "You must sign in or sign up to continue."
end end

View File

@@ -18,11 +18,11 @@ describe Legislation::Proposals::VotesComponent do
expect(page).not_to have_button "I disagree", disabled: :all expect(page).not_to have_button "I disagree", disabled: :all
end end
it "is disabled to anonymous users" do it "is shown to anonymous users alongside a reminder to sign in" do
render_inline component render_inline component
expect(page).to have_button "I agree", disabled: true expect(page).to have_button "I agree"
expect(page).to have_button "I disagree", disabled: true expect(page).to have_button "I disagree"
expect(page).to have_content "You must sign in or sign up to continue." expect(page).to have_content "You must sign in or sign up to continue."
end end

View File

@@ -5,12 +5,12 @@ describe Proposals::VotesComponent do
let(:component) { Proposals::VotesComponent.new(proposal) } let(:component) { Proposals::VotesComponent.new(proposal) }
describe "support proposal button" do describe "support proposal button" do
it "is disabled to unverified users" do it "is shown to unverified users" do
sign_in(create(:user)) sign_in(create(:user))
render_inline component render_inline component
expect(page).to have_button "Support", disabled: true expect(page).to have_button "Support"
end end
it "is shown to verified users" do it "is shown to verified users" do
@@ -38,8 +38,8 @@ describe Proposals::VotesComponent do
it "asks anonymous users to sign in or sign up" do it "asks anonymous users to sign in or sign up" do
render_inline component render_inline component
expect(page).to have_link "sign in", visible: :hidden expect(page).to have_link "sign in"
expect(page).to have_link "sign up", visible: :hidden expect(page).to have_link "sign up"
end end
it "says voting is not allowed to organizations" do it "says voting is not allowed to organizations" do
@@ -58,7 +58,7 @@ describe Proposals::VotesComponent do
render_inline component render_inline component
expect(page).to have_content "Only verified users can vote on proposals" expect(page).to have_content "Only verified users can vote on proposals"
expect(page).to have_link "verify your account", visible: :hidden expect(page).to have_link "verify your account"
expect(page).not_to have_link "sign in", visible: :all expect(page).not_to have_link "sign in", visible: :all
expect(page).not_to have_link "sign up", visible: :all expect(page).not_to have_link "sign up", visible: :all
end end

View File

@@ -0,0 +1,70 @@
require "rails_helper"
describe Shared::ParticipationNotAllowedComponent do
let(:votable) { create(:proposal) }
context "Without cannot vote text" do
let(:component) { Shared::ParticipationNotAllowedComponent.new(votable, cannot_vote_text: nil) }
it "asks anonymous users to sign in or sign up" do
render_inline component
expect(page).to have_content "You must sign in or sign up to continue"
expect(page).to have_link "sign in"
expect(page).to have_link "sign up"
end
it "says voting is not allowed to organizations" do
sign_in(create(:organization, user: create(:user, :level_two)).user)
render_inline component
expect(page).to have_content "Organizations are not permitted to vote"
expect(page).not_to have_link "sign in", visible: :all
expect(page).not_to have_link "sign up", visible: :all
end
it "is not rendered to regular users" do
sign_in(create(:user))
render_inline component
expect(page).not_to be_rendered
end
end
context "With cannot vote text" do
let(:component) { Shared::ParticipationNotAllowedComponent.new(votable, cannot_vote_text: "Too old") }
it "ignores the text and asks anonymous users to sign in or sign up" do
render_inline component
expect(page).to have_content "You must sign in or sign up to continue"
expect(page).to have_link "sign in"
expect(page).to have_link "sign up"
expect(page).not_to have_content "Too old"
end
it "ignores the text and says voting is not allowed to organizations" do
sign_in(create(:organization, user: create(:user, :level_two)).user)
render_inline component
expect(page).to have_content "Organizations are not permitted to vote"
expect(page).not_to have_link "sign in", visible: :all
expect(page).not_to have_link "sign up", visible: :all
expect(page).not_to have_content "Too old"
end
it "renders the cannot vote text to regular users" do
sign_in(create(:user))
render_inline component
expect(page).to have_content "Too old"
expect(page).not_to have_content "Organizations are not permitted to vote"
expect(page).not_to have_link "sign in", visible: :all
expect(page).not_to have_link "sign up", visible: :all
end
end
end

View File

@@ -13,7 +13,6 @@ module CommonActions
include Translations include Translations
include Users include Users
include Verifications include Verifications
include Votes
def app_host def app_host
"#{Capybara.app_host}:#{Capybara::Server.ports.values.last}" "#{Capybara.app_host}:#{Capybara::Server.ports.values.last}"

View File

@@ -4,11 +4,6 @@ module Budgets
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).to have_button "Vote", disabled: true, obscured: true
end end
def hover_over_ballot
scroll_to find("div.ballot"), align: :bottom
first("div.ballot p").hover
end
def add_to_ballot(investment_title) def add_to_ballot(investment_title)
within(".budget-investment", text: investment_title) do within(".budget-investment", text: investment_title) do
click_button "Vote" click_button "Vote"

View File

@@ -1,22 +0,0 @@
module Votes
def expect_message_you_need_to_sign_in
expect(page).to have_content "You must sign in or sign up to continue"
expect(page).to have_selector(".in-favor", obscured: true)
end
def expect_message_you_need_to_sign_in_to_vote_comments
within(".participation-not-allowed") do
expect(page).to have_content "You must sign in or sign up to vote"
end
end
def expect_message_to_many_anonymous_votes
expect(page).to have_content "Too many anonymous votes to admit vote"
expect(page).to have_button "I agree", obscured: true
end
def expect_message_only_verified_can_vote_proposals
expect(page).to have_content "Only verified users can vote on proposals"
expect(page).to have_selector(".in-favor", obscured: true)
end
end

View File

@@ -81,11 +81,12 @@ describe "BudgetPolls", :with_frozen_time do
login_as(user) login_as(user)
visit budget_investment_path(budget, investment) visit budget_investment_path(budget, investment)
first("div.ballot p").hover
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
click_button "Vote"
expect(page).to have_content "You have already participated offline" expect(page).to have_content "You have already participated offline"
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end
end end
@@ -111,7 +112,6 @@ describe "BudgetPolls", :with_frozen_time do
end end
visit budget_investment_path(budget, investment) visit budget_investment_path(budget, investment)
find("div.ballot").hover
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
expect(page).to have_content "Remove vote" expect(page).to have_content "Remove vote"

View File

@@ -446,10 +446,10 @@ describe "Ballots" do
visit budget_investments_path(budget, heading_id: new_york.id) visit budget_investments_path(budget, heading_id: new_york.id)
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
hover_over_ballot click_button "Vote"
expect(page).to have_content "You must sign in or sign up to continue." expect(page).to have_content "You must sign in or sign up to continue."
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end
@@ -461,10 +461,10 @@ describe "Ballots" do
visit budget_investments_path(budget, heading_id: new_york.id) visit budget_investments_path(budget, heading_id: new_york.id)
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
hover_over_ballot click_button "Vote"
expect(page).to have_content "Only verified users can vote on investments" expect(page).to have_content "Only verified users can vote on investments"
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end
@@ -476,9 +476,10 @@ describe "Ballots" do
visit budget_investments_path(budget, heading_id: new_york.id) visit budget_investments_path(budget, heading_id: new_york.id)
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
hover_over_ballot click_button "Vote"
expect_message_organizations_cannot_vote expect(page).to have_content "Organization"
expect(page).not_to have_button "Vote", disabled: :all
end end
end end
@@ -512,10 +513,10 @@ describe "Ballots" do
visit budget_investments_path(budget, heading: new_york) visit budget_investments_path(budget, heading: new_york)
within("#budget_investment_#{bi2.id}") do within("#budget_investment_#{bi2.id}") do
hover_over_ballot click_button "Vote"
expect(page).to have_content("already voted a different heading") expect(page).to have_content("already voted a different heading")
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end
@@ -528,10 +529,10 @@ describe "Ballots" do
visit budget_investments_path(budget, heading_id: california.id) visit budget_investments_path(budget, heading_id: california.id)
within("#budget_investment_#{bi2.id}") do within("#budget_investment_#{bi2.id}") do
hover_over_ballot click_button "Vote"
expect(page).to have_content("You have already assigned the available budget") expect(page).to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end
@@ -542,20 +543,13 @@ describe "Ballots" do
login_as(user) login_as(user)
visit budget_investments_path(budget, heading_id: california.id) visit budget_investments_path(budget, heading_id: california.id)
within(".budget-investment", text: "Build replicants") do
hover_over_ballot
expect(page).not_to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", obscured: false
end
add_to_ballot("Build replicants") add_to_ballot("Build replicants")
within(".budget-investment", text: "Build terminators") do within(".budget-investment", text: "Build terminators") do
hover_over_ballot click_button "Vote"
expect(page).to have_content("You have already assigned the available budget") expect(page).to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end
@@ -568,10 +562,11 @@ describe "Ballots" do
visit budget_investments_path(budget, heading_id: california.id) visit budget_investments_path(budget, heading_id: california.id)
within("#budget_investment_#{bi2.id}") do within("#budget_investment_#{bi2.id}") do
hover_over_ballot click_button "Vote"
expect(page).to have_content("You have already assigned the available budget") expect(page).to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
expect(page).not_to have_button "Remove vote"
end end
within("#budget_investment_#{bi1.id}") do within("#budget_investment_#{bi1.id}") do
@@ -580,10 +575,10 @@ describe "Ballots" do
end end
within("#budget_investment_#{bi2.id}") do within("#budget_investment_#{bi2.id}") do
hover_over_ballot click_button "Vote"
expect(page).not_to have_content("You have already assigned the available budget") expect(page).not_to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", obscured: false expect(page).to have_button "Remove vote"
end end
end end
@@ -596,10 +591,10 @@ describe "Ballots" do
visit budget_investments_path(budget, heading_id: california.id) visit budget_investments_path(budget, heading_id: california.id)
within("#budget_investment_#{bi2.id}") do within("#budget_investment_#{bi2.id}") do
hover_over_ballot click_button "Vote"
expect(page).to have_content("You have already assigned the available budget") expect(page).to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
within("#budget_investment_#{bi1.id}_sidebar") do within("#budget_investment_#{bi1.id}_sidebar") do
@@ -609,10 +604,10 @@ describe "Ballots" do
expect(page).not_to have_css "#budget_investment_#{bi1.id}_sidebar" expect(page).not_to have_css "#budget_investment_#{bi1.id}_sidebar"
within("#budget_investment_#{bi2.id}") do within("#budget_investment_#{bi2.id}") do
hover_over_ballot click_button "Vote"
expect(page).not_to have_content("You have already assigned the available budget") expect(page).not_to have_content("You have already assigned the available budget")
expect(page).to have_button "Vote", obscured: false expect(page).to have_button "Remove vote"
end end
end end
@@ -641,13 +636,13 @@ describe "Ballots" do
within("#budget_investment_#{investment1.id}") do within("#budget_investment_#{investment1.id}") do
click_button "Vote" click_button "Vote"
expect(page).to have_css ".participation-not-allowed", visible: :hidden
expect(page).not_to have_content "Remove" expect(page).not_to have_content "Remove"
expect(page).not_to have_selector(".participation-not-allowed")
hover_over_ballot click_button "Vote"
expect(page).to have_selector(".participation-not-allowed") expect(page).to have_css ".participation-not-allowed"
expect(page).to have_button "Vote", disabled: true, obscured: true expect(page).not_to have_button "Vote", disabled: :all
end end
end end

View File

@@ -229,9 +229,8 @@ describe "Votes" do
expect(page).to have_content("YOU CAN STILL CAST 1 VOTE") expect(page).to have_content("YOU CAN STILL CAST 1 VOTE")
within(".budget-investment", text: investment2.title) do within(".budget-investment", text: investment2.title) do
find("div.ballot").hover expect(page).not_to have_css ".participation-not-allowed", visible: :all
expect(page).not_to have_content "You have already assigned the available budget"
expect(page).not_to have_content("You have already assigned the available budget")
end end
visit budget_ballot_path(budget) visit budget_ballot_path(budget)

View File

@@ -252,8 +252,11 @@ describe "Votes" do
visit debates_path visit debates_path
within("#debate_#{debate.id}") do within("#debate_#{debate.id}") do
find("div.votes").hover click_button "I agree"
expect_message_you_need_to_sign_in
expect(page).to have_content "You must sign in or sign up to continue"
expect(page).to have_button "I agree", disabled: true
expect(page).to have_button "I disagree", disabled: true
end end
end end
@@ -262,14 +265,18 @@ describe "Votes" do
visit proposals_path visit proposals_path
within("#proposal_#{proposal.id}") do within("#proposal_#{proposal.id}") do
find("div.supports").hover click_button "Support"
expect_message_you_need_to_sign_in
expect(page).to have_content "You must sign in or sign up to continue"
expect(page).not_to have_button "Support", disabled: :all
end end
visit proposal_path(proposal) visit proposal_path(proposal)
within("#proposal_#{proposal.id}") do within("#proposal_#{proposal.id}") do
find("div.supports").hover click_button "Support"
expect_message_you_need_to_sign_in
expect(page).to have_content "You must sign in or sign up to continue"
expect(page).not_to have_button "Support", disabled: :all
end end
end end
@@ -278,10 +285,12 @@ describe "Votes" do
comment = create(:comment, commentable: debate) comment = create(:comment, commentable: debate)
visit comment_path(comment) visit comment_path(comment)
within("#comment_#{comment.id}") do within("#comment_#{comment.id}") do
find("div.votes").hover click_button "I agree"
expect_message_you_need_to_sign_in_to_vote_comments
end end
expect(page).to have_current_path new_user_session_path
end end
scenario "Not logged user trying to vote comments in proposals" do scenario "Not logged user trying to vote comments in proposals" do
@@ -289,10 +298,12 @@ describe "Votes" do
comment = create(:comment, commentable: proposal) comment = create(:comment, commentable: proposal)
visit comment_path(comment) visit comment_path(comment)
within("#comment_#{comment.id}_reply") do within("#comment_#{comment.id}_reply") do
find("div.votes").hover click_button "I agree"
expect_message_you_need_to_sign_in_to_vote_comments
end end
expect(page).to have_current_path new_user_session_path
end end
scenario "Anonymous user trying to vote debates" do scenario "Anonymous user trying to vote debates" do
@@ -306,14 +317,18 @@ describe "Votes" do
visit debates_path visit debates_path
within("#debate_#{debate.id}") do within("#debate_#{debate.id}") do
find("div.votes").hover click_button "I agree"
expect_message_to_many_anonymous_votes
expect(page).to have_content "Too many anonymous votes to admit vote"
expect(page).to have_button "I agree", disabled: true
end end
visit debate_path(debate) visit debate_path(debate)
within("#debate_#{debate.id}") do within("#debate_#{debate.id}") do
find("div.votes").hover click_button "I agree"
expect_message_to_many_anonymous_votes
expect(page).to have_content "Too many anonymous votes to admit vote"
expect(page).to have_button "I agree", disabled: true
end end
end end
@@ -325,14 +340,18 @@ describe "Votes" do
visit proposals_path visit proposals_path
within("#proposal_#{proposal.id}") do within("#proposal_#{proposal.id}") do
find("div.supports").hover click_button "Support"
expect_message_only_verified_can_vote_proposals
expect(page).to have_content "Only verified users can vote on proposals"
expect(page).not_to have_button "Support", disabled: :all
end end
visit proposal_path(proposal) visit proposal_path(proposal)
within("#proposal_#{proposal.id}") do within("#proposal_#{proposal.id}") do
find("div.supports").hover click_button "Support"
expect_message_only_verified_can_vote_proposals
expect(page).to have_content "Only verified users can vote on proposals"
expect(page).not_to have_button "Support", disabled: :all
end end
end end
end end