Merge branch 'master' into chore/update_secrets_example
This commit is contained in:
Binary file not shown.
@@ -62,4 +62,5 @@
|
||||
<glyph glyph-name="expand" unicode="0" d="M26 168l-26-158c0-2 1-5 3-7 0 0 0 0 0 0 2-2 5-3 7-3l158 27c3 0 6 3 7 6 1 3 0 7-3 9l-30 31 82 82c4 4 4 9 0 13l-57 57c-3 3-9 3-12 0l-83-83-31 31c-2 2-5 3-9 2-3-1-5-4-6-7z m460 176l26 158c0 2-1 5-3 7 0 0 0 0 0 0-2 2-5 3-7 3l-158-27c-3 0-6-3-7-6-1-3 0-7 3-9l30-31-82-82c-4-4-4-9 0-13l57-57c3-3 9-3 12 0l83 83 31-31c2-2 5-3 9-2 3 1 5 4 6 7z"/>
|
||||
<glyph glyph-name="telegram" unicode="1" d="M504 509c6-5 9-11 8-18l-73-439c-1-6-4-10-10-13-2-2-5-2-8-2-3 0-5 0-7 1l-130 53-69-84c-3-5-8-7-14-7-2 0-4 0-6 1-4 1-7 4-9 7-2 3-3 6-3 10l0 100 247 303-306-265-113 47c-7 2-10 7-11 15 0 8 3 14 9 17l476 274c2 2 5 3 9 3 4 0 7-1 10-3z"/>
|
||||
<glyph glyph-name="instagram" unicode="2" d="M426 105l0 185-39 0c4-12 6-25 6-38 0-24-6-46-18-66-13-20-29-36-50-48-21-12-44-18-69-18-37 0-69 13-96 39-27 26-40 57-40 93 0 13 2 26 6 38l-41 0 0-185c0-5 2-10 5-13 4-3 8-5 13-5l305 0c5 0 9 2 13 5 3 3 5 8 5 13z m-81 152c0 23-9 44-26 60-18 17-38 25-63 25-24 0-45-8-62-25-17-16-26-37-26-60 0-24 9-44 26-61 17-16 38-25 62-25 25 0 45 9 63 25 17 17 26 37 26 61z m81 103l0 47c0 5-2 10-6 14-4 4-8 6-14 6l-50 0c-5 0-10-2-14-6-4-4-5-9-5-14l0-47c0-6 1-10 5-14 4-4 9-6 14-6l50 0c6 0 10 2 14 6 4 4 6 8 6 14z m49 59l0-326c0-16-5-29-16-40-11-11-24-16-40-16l-326 0c-16 0-29 5-40 16-11 11-16 24-16 40l0 326c0 16 5 29 16 40 11 11 24 16 40 16l326 0c16 0 29-5 40-16 11-11 16-24 16-40z"/>
|
||||
<glyph glyph-name="image" unicode="3" d="M165 347c0-15-6-28-16-38-11-11-24-16-39-16-16 0-28 5-39 16-11 10-16 23-16 38 0 16 5 29 16 39 11 11 23 16 39 16 15 0 28-5 39-16 10-10 16-23 16-39z m292-109l0-128-402 0 0 55 91 91 46-46 146 147z m28 201l-458 0c-2 0-4-1-6-3-2-2-3-4-3-6l0-348c0-2 1-4 3-6 2-2 4-3 6-3l458 0c2 0 4 1 6 3 2 2 3 4 3 6l0 348c0 2-1 4-3 6-2 2-4 3-6 3z m45-9l0-348c0-12-4-23-13-32-9-9-20-13-32-13l-458 0c-12 0-23 4-32 13-9 9-13 20-13 32l0 348c0 12 4 23 13 32 9 9 20 13 32 13l458 0c12 0 23-4 32-13 9-9 13-20 13-32z"/>
|
||||
</font></defs></svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
Binary file not shown.
Binary file not shown.
@@ -97,10 +97,6 @@
|
||||
content: '\72';
|
||||
}
|
||||
|
||||
.icon-documents::before {
|
||||
content: '\68';
|
||||
}
|
||||
|
||||
.icon-proposals::before {
|
||||
content: '\68';
|
||||
}
|
||||
@@ -197,10 +193,6 @@
|
||||
content: '\53';
|
||||
}
|
||||
|
||||
.icon-image::before {
|
||||
content: '\68';
|
||||
}
|
||||
|
||||
.icon-notification::before {
|
||||
content: '\6e';
|
||||
}
|
||||
@@ -264,3 +256,7 @@
|
||||
.icon-instagram::before {
|
||||
content: '\32';
|
||||
}
|
||||
|
||||
.icon-image::before {
|
||||
content: '\33';
|
||||
}
|
||||
|
||||
@@ -354,6 +354,18 @@ a {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.aling-middle {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: table;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
// 02. Header
|
||||
// ----------
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
@mixin direct-uploads {
|
||||
|
||||
.cached-image {
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
max-width: rem-calc(150);
|
||||
max-height: rem-calc(150);
|
||||
}
|
||||
|
||||
.progress-bar-placeholder {
|
||||
@@ -78,15 +78,23 @@
|
||||
|
||||
.document-attachment,
|
||||
.image-attachment {
|
||||
padding-left:0;
|
||||
padding-left: 0;
|
||||
|
||||
p{
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
input.js-document-attachment,
|
||||
input.js-image-attachment{
|
||||
display: none;
|
||||
|
||||
.attachment-errors {
|
||||
|
||||
> .js-image-attachment,
|
||||
> .js-document-attachment {
|
||||
display: none;
|
||||
|
||||
~ .error {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -255,7 +255,6 @@
|
||||
.icon-debates,
|
||||
.icon-proposals,
|
||||
.icon-budget,
|
||||
.icon-documents,
|
||||
.icon-image {
|
||||
font-size: rem-calc(50);
|
||||
line-height: $line-height;
|
||||
@@ -267,7 +266,6 @@
|
||||
}
|
||||
|
||||
.icon-proposals,
|
||||
.icon-documents,
|
||||
.icon-image {
|
||||
color: $proposals;
|
||||
}
|
||||
@@ -312,12 +310,10 @@
|
||||
.budget-investment-new,
|
||||
.proposal-form,
|
||||
.proposal-edit,
|
||||
.new_poll_question,
|
||||
.edit_poll_question {
|
||||
.poll-question-form {
|
||||
@include direct-uploads;
|
||||
}
|
||||
|
||||
|
||||
// 03. Show participation
|
||||
// ----------------------
|
||||
|
||||
@@ -358,8 +354,7 @@
|
||||
width: rem-calc(48);
|
||||
}
|
||||
|
||||
.edit-debate,
|
||||
.edit-proposal {
|
||||
.edit-debate {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@@ -661,20 +656,17 @@
|
||||
.proposals-list .proposal {
|
||||
|
||||
@include breakpoint(small) {
|
||||
|
||||
.no-image {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
max-width: rem-calc(300);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.no-image::before {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.3rem;
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.column:first-child {
|
||||
@@ -683,19 +675,17 @@
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
|
||||
.panel {
|
||||
padding: 0 0.75rem 0 0;
|
||||
padding: 0 $line-height / 2 0 0;
|
||||
|
||||
.no-image {
|
||||
height: 245px;
|
||||
width: 140px;
|
||||
height: 100%;
|
||||
min-height: rem-calc(245);
|
||||
width: rem-calc(140);
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.column:first-child {
|
||||
overflow: hidden;
|
||||
}
|
||||
@@ -705,7 +695,7 @@
|
||||
}
|
||||
|
||||
.column:last-child:not(:first-child) {
|
||||
padding-top: 0.75rem;
|
||||
padding-top: $line-height / 2;
|
||||
}
|
||||
|
||||
img {
|
||||
@@ -1701,9 +1691,13 @@
|
||||
}
|
||||
|
||||
.section-title-divider {
|
||||
border-bottom: 2px solid $brand;
|
||||
color: $brand;
|
||||
margin-bottom: $line-height;
|
||||
border-bottom: 1px solid #eee;
|
||||
color: #000;
|
||||
margin: $line-height 0;
|
||||
|
||||
span {
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
}
|
||||
|
||||
.poll-question {
|
||||
|
||||
@@ -12,7 +12,8 @@ class Officing::VotersController < Officing::BaseController
|
||||
@voter = Poll::Voter.new(document_type: @user.document_type,
|
||||
document_number: @user.document_number,
|
||||
user: @user,
|
||||
poll: @poll)
|
||||
poll: @poll,
|
||||
origin: "booth")
|
||||
@voter.save!
|
||||
end
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ module Abilities
|
||||
|
||||
can [:read, :update, :valuate, :destroy, :summary], SpendingProposal
|
||||
|
||||
can [:index, :read, :new, :create, :update, :destroy, :calculate_winners], Budget
|
||||
can [:index, :read, :new, :create, :update, :destroy, :calculate_winners, :read_results], Budget
|
||||
can [:read, :create, :update, :destroy], Budget::Group
|
||||
can [:read, :create, :update, :destroy], Budget::Heading
|
||||
can [:hide, :update, :toggle_selection], Budget::Investment
|
||||
|
||||
@@ -59,6 +59,10 @@ class Poll < ActiveRecord::Base
|
||||
voters.where(document_number: document_number, document_type: document_type).exists?
|
||||
end
|
||||
|
||||
def voted_in_booth?(user)
|
||||
Poll::Voter.where(poll: self, user: user, origin: "booth").exists?
|
||||
end
|
||||
|
||||
def date_range
|
||||
unless starts_at.present? && ends_at.present? && starts_at <= ends_at
|
||||
errors.add(:starts_at, I18n.t('errors.messages.invalid_date_range'))
|
||||
|
||||
@@ -8,12 +8,13 @@ class Poll::Answer < ActiveRecord::Base
|
||||
validates :question, presence: true
|
||||
validates :author, presence: true
|
||||
validates :answer, presence: true
|
||||
validates :answer, inclusion: {in: ->(a) { a.question.valid_answers }}
|
||||
validates :answer, inclusion: { in: ->(a) { a.question.valid_answers }},
|
||||
unless: ->(a) { a.question.blank? }
|
||||
|
||||
scope :by_author, ->(author_id) { where(author_id: author_id) }
|
||||
scope :by_question, ->(question_id) { where(question_id: question_id) }
|
||||
|
||||
def record_voter_participation
|
||||
Poll::Voter.create!(user: author, poll: poll)
|
||||
Poll::Voter.find_or_create_by!(user: author, poll: poll, origin: "web")
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
class Poll::Recount < ActiveRecord::Base
|
||||
|
||||
VALID_ORIGINS = %w{ web booth letter }
|
||||
VALID_ORIGINS = %w{web booth letter}.freeze
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
belongs_to :booth_assignment
|
||||
@@ -22,7 +22,7 @@ class Poll::Recount < ActiveRecord::Base
|
||||
|
||||
[:white, :null, :total].each do |amount|
|
||||
next unless send("#{amount}_amount_changed?") && send("#{amount}_amount_was").present?
|
||||
self["#{amount}_amount_log"] += ":#{send("#{amount}_amount_was").to_s}"
|
||||
self["#{amount}_amount_log"] += ":#{send("#{amount}_amount_was")}"
|
||||
amounts_changed = true
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ class Poll::Recount < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def update_officer_author
|
||||
self.officer_assignment_id_log += ":#{officer_assignment_id_was.to_s}"
|
||||
self.author_id_log += ":#{author_id_was.to_s}"
|
||||
self.officer_assignment_id_log += ":#{officer_assignment_id_was}"
|
||||
self.author_id_log += ":#{author_id_was}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
class Poll
|
||||
class Voter < ActiveRecord::Base
|
||||
|
||||
VALID_ORIGINS = %w{ web booth }
|
||||
|
||||
belongs_to :poll
|
||||
belongs_to :user
|
||||
belongs_to :geozone
|
||||
@@ -10,9 +13,13 @@ class Poll
|
||||
validates :user_id, presence: true
|
||||
|
||||
validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted }
|
||||
validates :origin, inclusion: { in: VALID_ORIGINS }
|
||||
|
||||
before_validation :set_demographic_info, :set_document_info
|
||||
|
||||
scope :web, -> { where(origin: 'web') }
|
||||
scope :booth, -> { where(origin: 'booth') }
|
||||
|
||||
def set_demographic_info
|
||||
return if user.blank?
|
||||
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
|
||||
<h2><%= t("admin.questions.edit.title") %></h2>
|
||||
|
||||
<%= render "form", form_url: admin_question_path(@question) %>
|
||||
<div class="poll-question-form">
|
||||
<%= render "form", form_url: admin_question_path(@question) %>
|
||||
</div>
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
|
||||
<h2><%= t("admin.questions.new.title") %></h2>
|
||||
|
||||
<%= render "form", form_url: admin_questions_path %>
|
||||
<div class="poll-question-form">
|
||||
<%= render "form", form_url: admin_questions_path %>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<div id="<%= dom_id(investment) %>" class="budget-investment clear">
|
||||
<div class="panel">
|
||||
<div class="row">
|
||||
<div class="row" data-equalizer>
|
||||
|
||||
<div class="small-12 medium-3 large-2 column">
|
||||
<% if investment.image.present? %>
|
||||
<%= image_tag investment.image_url(:thumb), alt: investment.image.title %>
|
||||
<% else %>
|
||||
<div class="no-image"></div>
|
||||
<% end %>
|
||||
<div data-equalizer-watch>
|
||||
<% if investment.image.present? %>
|
||||
<%= image_tag investment.image_url(:thumb), alt: investment.image.title %>
|
||||
<% else %>
|
||||
<div class="no-image"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-6 large-7 column">
|
||||
@@ -53,7 +55,7 @@
|
||||
|
||||
<% if investment.should_show_votes? %>
|
||||
<div id="<%= dom_id(investment) %>_votes"
|
||||
class="small-12 medium-3 column text-center">
|
||||
class="small-12 medium-3 column text-center" data-equalizer-watch>
|
||||
<%= render partial: '/budgets/investments/votes', locals: {
|
||||
investment: investment,
|
||||
investment_votes: investment_votes,
|
||||
@@ -62,7 +64,7 @@
|
||||
</div>
|
||||
<% elsif investment.should_show_vote_count? %>
|
||||
<div id="<%= dom_id(investment) %>_votes"
|
||||
class="small-12 medium-3 column text-center">
|
||||
class="small-12 medium-3 column text-center" data-equalizer-watch>
|
||||
<div class="supports js-participation">
|
||||
<span class="total-supports no-button">
|
||||
<%= t("budgets.investments.investment.supports",
|
||||
@@ -72,7 +74,7 @@
|
||||
</div>
|
||||
<% elsif investment.should_show_ballots? %>
|
||||
<div id="<%= dom_id(investment) %>_ballot"
|
||||
class="small-12 medium-3 column text-center">
|
||||
class="small-12 medium-3 column text-center" data-equalizer-watch>
|
||||
<%= render partial: '/budgets/investments/ballot', locals: {
|
||||
investment: investment,
|
||||
investment_ids: investment_ids,
|
||||
@@ -81,11 +83,13 @@
|
||||
</div>
|
||||
<% elsif investment.should_show_price? %>
|
||||
<div id="<%= dom_id(investment) %>_price"
|
||||
class="supports small-12 medium-3 column text-center">
|
||||
class="supports small-12 medium-3 column text-center" data-equalizer-watch>
|
||||
<p class="investment-project-amount margin-top">
|
||||
<%= investment.formatted_price %>
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<div data-equalizer-watch></div>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if @budget.finished? %>
|
||||
<% if @budget.finished? || (@budget.balloting? && can?(:read_results, @budget)) %>
|
||||
<%= link_to t("budgets.show.see_results"),
|
||||
budget_results_path(@budget, heading_id: @budget.headings.first),
|
||||
class: "button margin-top expanded" %>
|
||||
|
||||
@@ -20,7 +20,4 @@
|
||||
<div id="max-documents-notice" class="max-documents-notice callout warning text-center <%= "hide" unless max_documents_allowed?(documentable) %>">
|
||||
<%= t "documents.max_documents_allowed_reached_html" %>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,4 +28,5 @@
|
||||
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
<div>
|
||||
<%= f.label :image, t("images.form.title") %>
|
||||
<p class="help-text"><%= imageables_note(imageable) %></p>
|
||||
<%= f.label :image, t("images.form.title") %>
|
||||
<p class="help-text"><%= imageables_note(imageable) %></p>
|
||||
|
||||
<div id="nested-image">
|
||||
<%= f.fields_for :image do |image_builder| %>
|
||||
<%= render 'images/image_fields', f: image_builder, imageable: imageable %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div id="nested-image">
|
||||
<%= f.fields_for :image do |image_builder| %>
|
||||
<%= render 'images/image_fields', f: image_builder, imageable: imageable %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= link_to_add_association t('images.form.add_new_image'), f, :image,
|
||||
@@ -21,5 +19,3 @@
|
||||
association_insertion_node: "#nested-image",
|
||||
association_insertion_method: "append"
|
||||
} %>
|
||||
|
||||
<hr>
|
||||
|
||||
@@ -33,23 +33,30 @@
|
||||
<span class="show-for-sr"><%= t("polls.index.cant_answer") %></span>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<div class="dates"><%= poll_dates(poll) %></div>
|
||||
<div class="row" data-equalizer>
|
||||
<div class="small-12 medium-3 column" data-equalizer-watch>
|
||||
<!-- PENDING TO REPLACE THIS BLOCK WITH POLL MAIN IMAGE -->
|
||||
<div style="background: #eee; width: 100%; height: 100%; display: block; margin: -12px;"> </div>
|
||||
<!-- /. PENDING TO REPLACE THIS BLOCK WITH POLL MAIN IMAGE -->
|
||||
</div>
|
||||
<div class="small-12 medium-6 column" data-equalizer-watch>
|
||||
<div class="dates"></div>
|
||||
<% if poll.questions.count == 1 %>
|
||||
<% poll.questions.each do |question| %>
|
||||
<h4 class="inline-block"><%= link_to question.title, poll %></h4>
|
||||
<h4><%= link_to question.title, poll %></h4>
|
||||
<%= poll_dates(poll) %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<h4 class="inline-block"><%= link_to poll.name, poll %></h4>
|
||||
<ul>
|
||||
<h4><%= link_to poll.name, poll %></h4>
|
||||
<%= poll_dates(poll) %>
|
||||
<ul class="margin-top">
|
||||
<% poll.questions.each do |question| %>
|
||||
<li><%= link_to question.title, question_path(question) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% if poll.geozones.any? %>
|
||||
<p class="inline-block">
|
||||
<p>
|
||||
<small><%= t("polls.index.geozone_info") %></small>
|
||||
</p>
|
||||
<% end %>
|
||||
@@ -59,16 +66,18 @@
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="small-12 medium-6 large-4 column end">
|
||||
<%= link_to poll, class: "button expanded" do %>
|
||||
<% if poll.expired? %>
|
||||
<%= t("polls.index.participate_button_expired") %>
|
||||
<% elsif poll.incoming? %>
|
||||
<%= t("polls.index.participate_button_incoming") %>
|
||||
<% else %>
|
||||
<%= t("polls.index.participate_button") %>
|
||||
<div class="small-12 medium-3 column table" data-equalizer-watch>
|
||||
<div class="table-cell aling-middle">
|
||||
<%= link_to poll, class: "button hollow expanded" do %>
|
||||
<% if poll.expired? %>
|
||||
<%= t("polls.index.participate_button_expired") %>
|
||||
<% elsif poll.incoming? %>
|
||||
<%= t("polls.index.participate_button_incoming") %>
|
||||
<% else %>
|
||||
<%= t("polls.index.participate_button") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,18 +6,22 @@
|
||||
<%= render "shared/section_header", i18n_namespace: "polls.index.section_header", image: "polls" %>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="small-12 column">
|
||||
<%= render 'shared/filter_subnav', i18n_namespace: "polls.index" %>
|
||||
|
||||
<% polls_by_geozone_restriction = @polls.group_by(&:geozone_restricted) %>
|
||||
|
||||
<% if polls_by_geozone_restriction[false].present? %>
|
||||
<h3 class="section-title-divider"><%= t("polls.index.no_geozone_restricted") %></h3>
|
||||
<h3 class="section-title-divider">
|
||||
<span><%= t("polls.index.no_geozone_restricted") %></span>
|
||||
</h3>
|
||||
<%= render partial: 'poll_group', locals: {poll_group: polls_by_geozone_restriction[false]} %>
|
||||
<% end %>
|
||||
|
||||
<% if polls_by_geozone_restriction[true].present? %>
|
||||
<h3 class="section-title-divider"><%= t("polls.index.geozone_restricted") %></h3>
|
||||
<h3 class="section-title-divider">
|
||||
<span><%= t("polls.index.geozone_restricted") %></span>
|
||||
</h3>
|
||||
<%= render partial: 'poll_group', locals: {poll_group: polls_by_geozone_restriction[true]} %>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -31,8 +31,14 @@
|
||||
|
||||
<div class="row margin-top">
|
||||
<div class="small-12 medium-9 column">
|
||||
<% @questions.each do |question| %>
|
||||
<%= render 'polls/questions/question', question: question %>
|
||||
<% if @poll.voted_in_booth?(current_user) %>
|
||||
<div class="callout warning">
|
||||
<%= t("polls.show.already_voted_in_booth") %>
|
||||
</div>
|
||||
<% else %>
|
||||
<% @questions.each do |question| %>
|
||||
<%= render 'polls/questions/question', question: question %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
data-type="proposal">
|
||||
<div class="panel">
|
||||
<div class="icon-successful"></div>
|
||||
<div class="row">
|
||||
<div class="row" data-equalizer>
|
||||
|
||||
<div class="small-12 medium-3 large-2 column">
|
||||
<% if proposal.image.present? %>
|
||||
<%= image_tag proposal.image_url(:thumb), alt: proposal.image.title %>
|
||||
<% else %>
|
||||
<div class="no-image"></div>
|
||||
<% end %>
|
||||
<div data-equalizer-watch>
|
||||
<% if proposal.image.present? %>
|
||||
<%= image_tag proposal.image_url(:thumb), alt: proposal.image.title %>
|
||||
<% else %>
|
||||
<div class="no-image"></div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-6 large-7 column">
|
||||
@@ -58,7 +60,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column supports-container">
|
||||
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column supports-container" data-equalizer-watch>
|
||||
<% if proposal.successful? %>
|
||||
<div class="padding text-center">
|
||||
|
||||
|
||||
@@ -117,6 +117,13 @@
|
||||
<h2><%= t("proposals.show.author") %></h2>
|
||||
<div class="show-actions-menu">
|
||||
|
||||
<% if current_editable?(@proposal) %>
|
||||
<%= link_to edit_proposal_path(@proposal), class: 'button hollow expanded' do %>
|
||||
<span class="icon-edit"></span>
|
||||
<%= t("proposals.show.edit_proposal_link") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if author_of_proposal?(@proposal) %>
|
||||
<%= link_to new_proposal_notification_path(proposal_id: @proposal.id),
|
||||
class: 'button hollow expanded' do %>
|
||||
@@ -128,20 +135,13 @@
|
||||
<% if can_destroy_image?(@proposal) %>
|
||||
<%= link_to image_path(@proposal.image, from: request.url),
|
||||
method: :delete,
|
||||
class: 'button hollow expanded',
|
||||
class: 'button hollow alert expanded',
|
||||
data: { confirm: t('images.actions.destroy.confirm') } do %>
|
||||
<span class="icon-document"></span>
|
||||
<span class="icon-image"></span>
|
||||
<%= t("images.remove_image") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if current_editable?(@proposal) %>
|
||||
<%= link_to edit_proposal_path(@proposal), class: 'edit-proposal button hollow expanded' do %>
|
||||
<span class="icon-edit"></span>
|
||||
<%= t("proposals.show.edit_proposal_link") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -481,6 +481,7 @@ en:
|
||||
help_text_1: "Voting takes place when a citizen proposal supports reaches 1% of the census with voting rights. Voting can also include questions that the City Council ask to the citizens decision."
|
||||
help_text_2: "To participate in the next vote you have to sign up on %{org} and verify your account. All registered voters in the city over 16 years old can vote. The results of all votes are binding on the government."
|
||||
show:
|
||||
already_voted_in_booth: "You have already participated in a booth for this poll."
|
||||
dates_title: "Participation dates"
|
||||
cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate."
|
||||
signin: Sign in
|
||||
|
||||
@@ -481,6 +481,7 @@ es:
|
||||
help_text_1: "Las votaciones se convocan cuando una propuesta ciudadana alcanza el 1% de apoyos del censo con derecho a voto. En las votaciones también se pueden incluir cuestiones que el Ayuntamiento somete a decisión directa de la ciudadanía."
|
||||
help_text_2: "Para participar en la próxima votación tienes que registrarte en %{org} y verificar tu cuenta. Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años. Los resultados de todas las votaciones serán vinculantes para el gobierno."
|
||||
show:
|
||||
already_voted_in_booth: "Ya has participado en esta votación en una urna."
|
||||
dates_title: "Fechas de participación"
|
||||
cant_answer_not_logged_in: "Necesitas %{signin} o %{signup} para participar."
|
||||
signin: iniciar sesión
|
||||
|
||||
5
db/migrate/20171002121658_add_origin_to_poll_voters.rb
Normal file
5
db/migrate/20171002121658_add_origin_to_poll_voters.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddOriginToPollVoters < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :poll_voters, :origin, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,7 @@
|
||||
class AddDefaultToRecountAmounts < ActiveRecord::Migration
|
||||
def change
|
||||
change_column_default :poll_recounts, :white_amount, 0
|
||||
change_column_default :poll_recounts, :null_amount, 0
|
||||
change_column_default :poll_recounts, :total_amount, 0
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20171002122312) do
|
||||
ActiveRecord::Schema.define(version: 20171002191347) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -698,11 +698,11 @@ ActiveRecord::Schema.define(version: 20171002122312) do
|
||||
t.integer "officer_assignment_id"
|
||||
t.text "officer_assignment_id_log", default: ""
|
||||
t.text "author_id_log", default: ""
|
||||
t.integer "white_amount"
|
||||
t.integer "white_amount", default: 0
|
||||
t.text "white_amount_log", default: ""
|
||||
t.integer "null_amount"
|
||||
t.integer "null_amount", default: 0
|
||||
t.text "null_amount_log", default: ""
|
||||
t.integer "total_amount"
|
||||
t.integer "total_amount", default: 0
|
||||
t.text "total_amount_log", default: ""
|
||||
end
|
||||
|
||||
@@ -752,6 +752,7 @@ ActiveRecord::Schema.define(version: 20171002122312) do
|
||||
t.integer "answer_id"
|
||||
t.integer "officer_assignment_id"
|
||||
t.integer "user_id"
|
||||
t.string "origin"
|
||||
end
|
||||
|
||||
add_index "poll_voters", ["booth_assignment_id"], name: "index_poll_voters_on_booth_assignment_id", using: :btree
|
||||
|
||||
@@ -52,6 +52,12 @@ FactoryGirl.define do
|
||||
trait :verified do
|
||||
verified_at Time.current
|
||||
end
|
||||
|
||||
trait :in_census do
|
||||
document_number "12345678Z"
|
||||
document_type "1"
|
||||
verified_at Time.current
|
||||
end
|
||||
end
|
||||
|
||||
factory :identity do
|
||||
@@ -525,6 +531,7 @@ FactoryGirl.define do
|
||||
factory :poll_voter, class: 'Poll::Voter' do
|
||||
poll
|
||||
association :user, :level_two
|
||||
origin "web"
|
||||
|
||||
trait :from_booth do
|
||||
association :booth_assignment, factory: :poll_booth_assignment
|
||||
|
||||
@@ -22,11 +22,6 @@ feature "Home" do
|
||||
|
||||
feature "For signed in users" do
|
||||
|
||||
before do
|
||||
# user = create(:user)
|
||||
# login_as(user)
|
||||
end
|
||||
|
||||
feature "Recommended" do
|
||||
|
||||
background do
|
||||
|
||||
@@ -184,6 +184,7 @@ feature 'Polls' do
|
||||
poll.geozones << geozone
|
||||
create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca')
|
||||
user = create(:user, :level_two, geozone: geozone)
|
||||
|
||||
login_as user
|
||||
visit poll_path(poll)
|
||||
|
||||
@@ -193,5 +194,25 @@ feature 'Polls' do
|
||||
expect(page).to have_link('Chewbacca')
|
||||
end
|
||||
|
||||
scenario 'Level 2 users changing answer', :js do
|
||||
poll.update(geozone_restricted: true)
|
||||
poll.geozones << geozone
|
||||
create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca')
|
||||
user = create(:user, :level_two, geozone: geozone)
|
||||
|
||||
login_as user
|
||||
visit poll_path(poll)
|
||||
|
||||
click_link 'Han Solo'
|
||||
|
||||
expect(page).to_not have_link('Han Solo')
|
||||
expect(page).to have_link('Chewbacca')
|
||||
|
||||
click_link 'Chewbacca'
|
||||
|
||||
expect(page).to_not have_link('Chewbacca')
|
||||
expect(page).to have_link('Han Solo')
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
94
spec/features/polls/voter_spec.rb
Normal file
94
spec/features/polls/voter_spec.rb
Normal file
@@ -0,0 +1,94 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature "Voter" do
|
||||
|
||||
context "Origin" do
|
||||
|
||||
scenario "Voting via web", :js do
|
||||
poll = create(:poll)
|
||||
question = create(:poll_question, poll: poll, valid_answers: 'Yes, No')
|
||||
user = create(:user, :level_two)
|
||||
|
||||
login_as user
|
||||
visit question_path(question)
|
||||
|
||||
click_link 'Answer this question'
|
||||
click_link 'Yes'
|
||||
|
||||
expect(page).to_not have_link('Yes')
|
||||
expect(Poll::Voter.count).to eq(1)
|
||||
expect(Poll::Voter.first.origin).to eq("web")
|
||||
end
|
||||
|
||||
scenario "Voting in booth", :js do
|
||||
user = create(:user, :in_census)
|
||||
create(:geozone, :in_census)
|
||||
|
||||
poll = create(:poll)
|
||||
officer = create(:poll_officer)
|
||||
|
||||
ba = create(:poll_booth_assignment, poll: poll)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba)
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
expect(page).to have_content poll.name
|
||||
|
||||
first(:button, "Confirm vote").click
|
||||
expect(page).to have_content "Vote introduced!"
|
||||
|
||||
expect(Poll::Voter.count).to eq(1)
|
||||
expect(Poll::Voter.first.origin).to eq("booth")
|
||||
end
|
||||
|
||||
context "Trying to vote the same poll in booth and web" do
|
||||
|
||||
let(:poll) { create(:poll) }
|
||||
let(:question) { create(:poll_question, poll: poll, valid_answers: 'Yes, No') }
|
||||
let!(:user) { create(:user, :in_census) }
|
||||
|
||||
let(:officer) { create(:poll_officer) }
|
||||
let(:ba) { create(:poll_booth_assignment, poll: poll) }
|
||||
let!(:oa) { create(:poll_officer_assignment, officer: officer, booth_assignment: ba) }
|
||||
|
||||
scenario "Trying to vote in web and then in booth", :js do
|
||||
login_as user
|
||||
vote_for_poll_via_web
|
||||
|
||||
click_link "Sign out"
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
expect(page).to have_content poll.name
|
||||
expect(page).to_not have_button "Confirm vote"
|
||||
expect(page).to have_content "Has already participated in this poll"
|
||||
end
|
||||
|
||||
scenario "Trying to vote in booth and then in web", :js do
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
vote_for_poll_via_booth
|
||||
|
||||
visit root_path
|
||||
click_link "Sign out"
|
||||
|
||||
login_as user
|
||||
visit question_path(question)
|
||||
|
||||
click_link 'Answer this question'
|
||||
|
||||
expect(page).to_not have_link('Yes')
|
||||
expect(page).to have_content "You have already participated in a booth for this poll."
|
||||
expect(Poll::Voter.count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -72,6 +72,7 @@ describe "Abilities::Administrator" do
|
||||
|
||||
it { should be_able_to(:create, Budget) }
|
||||
it { should be_able_to(:update, Budget) }
|
||||
it { should be_able_to(:read_results, Budget) }
|
||||
|
||||
it { should be_able_to(:create, Budget::ValuatorAssignment) }
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ describe "Abilities::Everyone" do
|
||||
let(:debate) { create(:debate) }
|
||||
let(:proposal) { create(:proposal) }
|
||||
|
||||
let(:reviewing_ballot_budget) { create(:budget, phase: 'reviewing_ballots') }
|
||||
let(:finished_budget) { create(:budget, phase: 'finished') }
|
||||
|
||||
it { should be_able_to(:index, Debate) }
|
||||
it { should be_able_to(:show, debate) }
|
||||
it { should_not be_able_to(:edit, Debate) }
|
||||
@@ -28,4 +31,7 @@ describe "Abilities::Everyone" do
|
||||
it { should_not be_able_to(:create, SpendingProposal) }
|
||||
|
||||
it { should be_able_to(:index, Budget) }
|
||||
end
|
||||
|
||||
it { should be_able_to(:read_results, finished_budget) }
|
||||
it { should_not be_able_to(:read_results, reviewing_ballot_budget) }
|
||||
end
|
||||
|
||||
@@ -3,28 +3,71 @@ require 'rails_helper'
|
||||
describe Poll::Answer do
|
||||
|
||||
describe "validations" do
|
||||
it "validates that the answers are included in the Poll::Question's list" do
|
||||
q = create(:poll_question, valid_answers: 'One, Two, Three')
|
||||
expect(build(:poll_answer, question: q, answer: 'One')).to be_valid
|
||||
expect(build(:poll_answer, question: q, answer: 'Two')).to be_valid
|
||||
expect(build(:poll_answer, question: q, answer: 'Three')).to be_valid
|
||||
|
||||
expect(build(:poll_answer, question: q, answer: 'Four')).to_not be_valid
|
||||
let(:answer) { build(:poll_answer) }
|
||||
|
||||
it "should be valid" do
|
||||
expect(answer).to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid wihout a question" do
|
||||
answer.question = nil
|
||||
expect(answer).to_not be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an author" do
|
||||
answer.author = nil
|
||||
expect(answer).to_not be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an answer" do
|
||||
answer.answer = nil
|
||||
expect(answer).to_not be_valid
|
||||
end
|
||||
|
||||
it "should be valid for answers included in the Poll::Question's list" do
|
||||
question = create(:poll_question, valid_answers: 'One, Two, Three')
|
||||
expect(build(:poll_answer, question: question, answer: 'One')).to be_valid
|
||||
expect(build(:poll_answer, question: question, answer: 'Two')).to be_valid
|
||||
expect(build(:poll_answer, question: question, answer: 'Three')).to be_valid
|
||||
|
||||
expect(build(:poll_answer, question: question, answer: 'Four')).to_not be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#record_voter_participation" do
|
||||
|
||||
let(:author) { create(:user, :level_two) }
|
||||
let(:poll) { create(:poll) }
|
||||
let(:question) { create(:poll_question, poll: poll, valid_answers: "Yes, No") }
|
||||
|
||||
it "creates a poll_voter with user and poll data" do
|
||||
answer = create(:poll_answer)
|
||||
answer = create(:poll_answer, question: question, author: author, answer: "Yes")
|
||||
expect(answer.poll.voters).to be_blank
|
||||
|
||||
answer.record_voter_participation
|
||||
expect(answer.poll.reload.voters.size).to eq(1)
|
||||
voter = answer.poll.voters.first
|
||||
expect(poll.reload.voters.size).to eq(1)
|
||||
voter = poll.voters.first
|
||||
|
||||
expect(voter.document_number).to eq(answer.author.document_number)
|
||||
expect(voter.poll_id).to eq(answer.poll.id)
|
||||
end
|
||||
|
||||
it "updates a poll_voter with user and poll data" do
|
||||
answer = create(:poll_answer, question: question, author: author, answer: "Yes")
|
||||
answer.record_voter_participation
|
||||
|
||||
expect(poll.reload.voters.size).to eq(1)
|
||||
|
||||
answer = create(:poll_answer, question: question, author: author, answer: "No")
|
||||
answer.record_voter_participation
|
||||
|
||||
expect(poll.reload.voters.size).to eq(1)
|
||||
|
||||
voter = poll.voters.first
|
||||
expect(voter.document_number).to eq(answer.author.document_number)
|
||||
expect(voter.poll_id).to eq(answer.poll.id)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -138,4 +138,33 @@ describe :poll do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#voted_in_booth?" do
|
||||
|
||||
it "returns true if the user has already voted in booth" do
|
||||
user = create(:user, :level_two)
|
||||
poll = create(:poll)
|
||||
|
||||
create(:poll_voter, poll: poll, user: user, origin: "booth")
|
||||
|
||||
expect(poll.voted_in_booth?(user)).to be
|
||||
end
|
||||
|
||||
it "returns false if the user has not already voted in a booth" do
|
||||
user = create(:user, :level_two)
|
||||
poll = create(:poll)
|
||||
|
||||
expect(poll.voted_in_booth?(user)).to_not be
|
||||
end
|
||||
|
||||
it "returns false if the user has voted in web" do
|
||||
user = create(:user, :level_two)
|
||||
poll = create(:poll)
|
||||
|
||||
create(:poll_voter, poll: poll, user: user, origin: "web")
|
||||
|
||||
expect(poll.voted_in_booth?(user)).to_not be
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ describe Poll::Recount do
|
||||
poll_recount.white_amount = 34
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq(":33:32")
|
||||
expect(poll_recount.white_amount_log).to eq(":0:33:32")
|
||||
end
|
||||
|
||||
it "should update null_amount_log if null_amount changes" do
|
||||
@@ -32,7 +32,7 @@ describe Poll::Recount do
|
||||
poll_recount.null_amount = 34
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.null_amount_log).to eq(":33:32")
|
||||
expect(poll_recount.null_amount_log).to eq(":0:33:32")
|
||||
end
|
||||
|
||||
it "should update total_amount_log if total_amount changes" do
|
||||
@@ -47,7 +47,7 @@ describe Poll::Recount do
|
||||
poll_recount.total_amount = 34
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.total_amount_log).to eq(":33:32")
|
||||
expect(poll_recount.total_amount_log).to eq(":0:33:32")
|
||||
end
|
||||
|
||||
it "should update officer_assignment_id_log if amount changes" do
|
||||
@@ -68,7 +68,7 @@ describe Poll::Recount do
|
||||
poll_recount.officer_assignment = create(:poll_officer_assignment, id: 103)
|
||||
poll_recount.save
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq(":33:32")
|
||||
expect(poll_recount.white_amount_log).to eq(":0:33:32")
|
||||
expect(poll_recount.officer_assignment_id_log).to eq(":101:102")
|
||||
end
|
||||
|
||||
@@ -78,24 +78,24 @@ describe Poll::Recount do
|
||||
expect(poll_recount.white_amount_log).to eq("")
|
||||
expect(poll_recount.author_id_log).to eq("")
|
||||
|
||||
author_A = create(:poll_officer).user
|
||||
author_B = create(:poll_officer).user
|
||||
author_C = create(:poll_officer).user
|
||||
first_author = create(:poll_officer).user
|
||||
second_author = create(:poll_officer).user
|
||||
third_author = create(:poll_officer).user
|
||||
|
||||
poll_recount.white_amount = 33
|
||||
poll_recount.author_id = author_A.id
|
||||
poll_recount.author_id = first_author.id
|
||||
poll_recount.save!
|
||||
|
||||
poll_recount.white_amount = 32
|
||||
poll_recount.author_id = author_B.id
|
||||
poll_recount.author_id = second_author.id
|
||||
poll_recount.save!
|
||||
|
||||
poll_recount.white_amount = 34
|
||||
poll_recount.author_id = author_C.id
|
||||
poll_recount.author_id = third_author.id
|
||||
poll_recount.save!
|
||||
|
||||
expect(poll_recount.white_amount_log).to eq(":33:32")
|
||||
expect(poll_recount.author_id_log).to eq(":#{author_A.id}:#{author_B.id}")
|
||||
expect(poll_recount.white_amount_log).to eq(":0:33:32")
|
||||
expect(poll_recount.author_id_log).to eq(":#{first_author.id}:#{second_author.id}:#{third_author.id}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -83,6 +83,64 @@ describe :voter do
|
||||
expect(voter.errors.messages[:document_number]).to eq(["User has already voted"])
|
||||
end
|
||||
|
||||
context "origin" do
|
||||
|
||||
it "should not be valid without an origin" do
|
||||
voter.origin = nil
|
||||
expect(voter).to_not be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without a valid origin" do
|
||||
voter.origin = "invalid_origin"
|
||||
expect(voter).to_not be_valid
|
||||
end
|
||||
|
||||
it "should be valid with a booth origin" do
|
||||
voter.origin = "booth"
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
it "should be valid with a web origin" do
|
||||
voter.origin = "web"
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "scopes" do
|
||||
|
||||
describe "#web" do
|
||||
it "returns voters with a web origin" do
|
||||
voter1 = create(:poll_voter, origin: "web")
|
||||
voter2 = create(:poll_voter, origin: "web")
|
||||
voter3 = create(:poll_voter, origin: "booth")
|
||||
|
||||
web_voters = Poll::Voter.web
|
||||
|
||||
expect(web_voters.count).to eq(2)
|
||||
expect(web_voters).to include(voter1)
|
||||
expect(web_voters).to include(voter2)
|
||||
expect(web_voters).to_not include(voter3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#booth" do
|
||||
it "returns voters with a booth origin" do
|
||||
voter1 = create(:poll_voter, origin: "booth")
|
||||
voter2 = create(:poll_voter, origin: "booth")
|
||||
voter3 = create(:poll_voter, origin: "web")
|
||||
|
||||
booth_voters = Poll::Voter.booth
|
||||
|
||||
expect(booth_voters.count).to eq(2)
|
||||
expect(booth_voters).to include(voter1)
|
||||
expect(booth_voters).to include(voter2)
|
||||
expect(booth_voters).to_not include(voter3)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "save" do
|
||||
|
||||
@@ -24,6 +24,17 @@ module CommonActions
|
||||
click_button 'Enter'
|
||||
end
|
||||
|
||||
def login_through_form_as_officer(user)
|
||||
visit root_path
|
||||
click_link 'Sign in'
|
||||
|
||||
fill_in 'user_login', with: user.email
|
||||
fill_in 'user_password', with: user.password
|
||||
|
||||
click_button 'Enter'
|
||||
visit new_officing_residence_path
|
||||
end
|
||||
|
||||
def login_as_authenticated_manager
|
||||
expected_response = {login: login, user_key: user_key, date: date}.with_indifferent_access
|
||||
login, user_key, date = "JJB042", "31415926", Time.current.strftime("%Y%m%d%H%M%S")
|
||||
@@ -287,4 +298,26 @@ module CommonActions
|
||||
end
|
||||
end
|
||||
|
||||
def vote_for_poll_via_web
|
||||
visit question_path(question)
|
||||
|
||||
click_link 'Answer this question'
|
||||
click_link 'Yes'
|
||||
|
||||
expect(page).to_not have_link('Yes')
|
||||
expect(Poll::Voter.count).to eq(1)
|
||||
end
|
||||
|
||||
def vote_for_poll_via_booth
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
expect(page).to have_content poll.name
|
||||
|
||||
first(:button, "Confirm vote").click
|
||||
expect(page).to have_content "Vote introduced!"
|
||||
|
||||
expect(Poll::Voter.count).to eq(1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user