Remove poll votation types

Unfortunately this feature wasn't properly reviewed and tested, and it
had many bugs, some of them critical and hard to fix, like validations
being skipped in concurrent requests.

So we're removing it before releasing version 1.1. We might add it back
in the future if we manage to solve the critical issues.

This commit reverts commit 836f9ba7.
This commit is contained in:
Javi Martín
2019-10-30 18:48:55 +01:00
parent f3df3f4fbc
commit af7c37634d
53 changed files with 173 additions and 2244 deletions

View File

@@ -87,7 +87,6 @@
//= require cookies //= require cookies
//= require columns_selector //= require columns_selector
//= require budget_edit_associations //= require budget_edit_associations
//= require votations
var initialize_modules = function() { var initialize_modules = function() {
"use strict"; "use strict";
@@ -143,9 +142,6 @@ var initialize_modules = function() {
App.ColumnsSelector.initialize(); App.ColumnsSelector.initialize();
} }
App.BudgetEditAssociations.initialize(); App.BudgetEditAssociations.initialize();
if ($("#votation_type_enum_type").length) {
App.Votations.initialize();
}
}; };
$(function() { $(function() {

View File

@@ -17,21 +17,6 @@
}); });
} }
}); });
$(".sortable-priotirized-votation").sortable({
update: function() {
var new_order;
new_order = $(this).sortable("toArray", {
attribute: "data-answer-id"
});
$.ajax({
url: $(this).data("js-url"),
data: {
ordered_list: new_order
},
type: "POST"
});
}
});
} }
}; };
}).call(this); }).call(this);

View File

@@ -1,56 +0,0 @@
(function() {
"use strict";
App.Votations = {
checkMaxVotes: function() {
if ($("#votation_type_enum_type").val() === "0") {
$(".js-max_votes").hide();
$("#max_votes").attr({ disabled: true });
} else {
$(".js-max_votes").show();
$("#max_votes").attr({ disabled: false });
}
},
checkPrioritization: function() {
if ($("#votation_type_enum_type").val() === "2") {
$(".js-prioritization_type").show();
$("#prioritization_type").attr({ disabled: false });
} else {
$(".js-prioritization_type").hide();
$("#prioritization_type").attr({ disabled: true });
}
},
checkMaxGroups: function() {
if ($("#votation_type_enum_type").val() === "7" || $("#votation_type_enum_type").val() === "8") {
$(".js-max_group_votes").show();
$("#max_groups_answers").attr({ disabled: false });
} else {
$(".js-max_group_votes").hide();
$("#max_groups_answers").attr({ disabled: true });
}
},
setTraduction: function(response) {
$(".js-description_text").text(response.traduction);
},
updateChecks: function() {
App.Votations.checkMaxVotes();
App.Votations.checkPrioritization();
App.Votations.checkMaxGroups();
},
initialize: function() {
App.Votations.updateChecks();
$("#votation_type_enum_type").on({
change: function() {
var params, url;
App.Votations.updateChecks();
url = "/admin/get_options_traductions.json";
params = {
enum_type: $("#votation_type_enum_type").val()
};
$.get(url, params, function(response) {
App.Votations.setTraduction(response, "json");
});
}
});
}
};
}).call(this);

View File

@@ -786,10 +786,6 @@ code {
font-weight: bold; font-weight: bold;
} }
.hidden {
display: none;
}
table { table {
.callout { .callout {
@@ -800,15 +796,6 @@ table {
} }
} }
.info-type {
background-color: #ccf5ff;
padding: 15px;
}
.margin-description {
margin-top: rem-calc(20);
}
// 07. Legislation // 07. Legislation
// -------------- // --------------

View File

@@ -1740,12 +1740,8 @@
background: #fafafa; background: #fafafa;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
.margin-bottom { .column:nth-child(odd) {
margin-bottom: 0; border-right: 2px solid $text;
}
.orbit-bullets {
margin-bottom: 0;
} }
.answer-divider { .answer-divider {
@@ -1755,35 +1751,14 @@
padding-bottom: $line-height; padding-bottom: $line-height;
} }
.answer-left-divider {
border-left: solid 1px $text;
padding-left: rem-calc(10);
}
.margin-top {
margin-top: rem-calc(10);
}
.margin-bottom {
margin-bottom: rem-calc(20);
}
.answer-description { .answer-description {
max-height: rem-calc(1000); height: 100%;
&.short { &.short {
max-height: rem-calc(70); height: rem-calc(300);
overflow: hidden; overflow: hidden;
max-width: rem-calc(700);
} }
} }
.question-divider {
border-bottom: rgba(219, 219, 219, 0.62) solid 1px;
margin-bottom: 1rem;
padding: rem-calc(24);
}
} }
.orbit-bullets button { .orbit-bullets button {
@@ -2011,69 +1986,6 @@
} }
} }
.icon-like,
.icon-unlike {
background: #fff;
border: 2px solid $text-light;
border-radius: rem-calc(3);
color: $text-light;
display: inline-block;
font-size: rem-calc(30);
line-height: rem-calc(30);
padding: rem-calc(3) rem-calc(6);
position: relative;
&:hover,
&:active {
color: #fff;
cursor: pointer;
opacity: 1 !important;
}
}
.active-like {
color: #fff;
cursor: pointer;
opacity: 1 !important;
background: $like;
border: 2px solid $like;
}
.active-unlike {
color: #fff;
cursor: pointer;
opacity: 1 !important;
background: $unlike;
border: 2px solid $unlike;
}
.icon-like {
&:hover,
&:active,
.picked {
background: $like;
border: 2px solid $like;
}
}
.icon-unlike {
&:hover,
&:active {
background: $unlike;
border: 2px solid $unlike;
}
}
.vote-align {
float: right;
}
.vote-divider {
border-bottom: 1px solid $text-light;
}
// 09. Polls results and stats // 09. Polls results and stats
// --------------------------- // ---------------------------

View File

@@ -22,7 +22,6 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
def create def create
@question.author = @question.proposal&.author || current_user @question.author = @question.proposal&.author || current_user
@question.votation_type = VotationType.build_by_type(@question, params[:votation_type])
if @question.save if @question.save
redirect_to admin_question_path(@question) redirect_to admin_question_path(@question)
@@ -54,18 +53,11 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
redirect_to admin_questions_path, notice: notice redirect_to admin_questions_path, notice: notice
end end
def get_options_traductions
render json: {
traduction: t("polls.index.descriptions.#{VotationType.enum_types.key params[:enum_type].to_i}")
}
end
private private
def question_params def question_params
attributes = [:poll_id, :question, :proposal_id] attributes = [:poll_id, :question, :proposal_id]
params.require(:poll_question).permit(*attributes, translation_params(Poll::Question), params.require(:poll_question).permit(*attributes, translation_params(Poll::Question))
:votation_type, :max_votes, :prioritization_type, :max_groups_answers)
end end
def search_params def search_params

View File

@@ -1,67 +0,0 @@
class Polls::AnswersController < ApplicationController
load_and_authorize_resource :poll
load_and_authorize_resource :question, class: "Poll::Question"
authorize_resource :answer, class: "Poll::Answer"
def create
@question = Poll::Question.find_by(id: params[:id])
if @question.votation_type.open? && !check_question_answer_exist
@question.question_answers.create!(
title: params[:answer],
given_order: @question.question_answers.maximum(:given_order).to_i + 1,
hidden: false
)
flash.now[:notice] = t("dashboard.polls.index.succesfull")
else
flash.now[:alert] = "Unfortunately failed to sent"
end
load_for_answers
if @question.enum_type&.include?("answer_couples")
last_pair ||= generate_and_store_new_pair(@question)
@last_pair_question_answers = { @question.id => last_pair }
end
render "polls/questions/answer", format: :js
end
def delete
@question = Poll::Question.find_by(id: params[:id])
!@question.answers.find_by(author: current_user, answer: params[:answer]).destroy
@question.question_answers.each(&:set_most_voted)
question_answers
load_for_answers
if @question.enum_type&.include?("answer_couples")
last_pair ||= generate_and_store_new_pair(@question)
@last_pair_question_answers = { @question.id => last_pair }
end
render "polls/questions/answer", format: :js
end
private
def check_question_answer_exist
exist = false
@question.question_answers.each do |question_answer|
break if exist
exist = true if question_answer.title == params[:answer]
end
exist
end
def load_for_answers
@page = params[:page].presence || 1
question_answers
@answers_by_question_id = { @question.id => @question.answers
.by_author(current_user)
.order(:order)
.pluck(:answer) }
end
def question_answers
if @question.is_positive_negative?
@answers = @question.question_answers.visibles.page(params[:page])
else
@answers = @question.question_answers.visibles
end
end
end

View File

@@ -5,73 +5,14 @@ class Polls::QuestionsController < ApplicationController
has_orders %w[most_voted newest oldest], only: :show has_orders %w[most_voted newest oldest], only: :show
def answer def answer
answer = store_answer answer = @question.answers.find_or_initialize_by(author: current_user)
vote_stored(answer, params[:answer], params[:token]) if answer.present? token = params[:token]
load_for_answers
if @question.enum_type&.include?("answer_couples") answer.answer = params[:answer]
last_pair ||= generate_and_store_new_pair(@question) answer.touch if answer.persisted?
@last_pair_question_answers = { @question.id => last_pair } answer.save!
end answer.record_voter_participation(token)
@answers_by_question_id = { @question.id => params[:answer] }
end end
def load_answers
load_for_answers
render action: "answer.js.erb"
end
def prioritized_answers
unless params[:ordered_list].empty?
params[:ordered_list].each_with_index do |answer, i|
answer_obj = @question.votation_type.answer(current_user,
answer,
order: i + 1)
vote_stored(answer_obj, answer, params[:tooken]) if answer_obj.present?
end
@question.votation_type.update_priorized_values(current_user.id)
end
load_for_answers
render action: "answer.js.erb"
end
private
def load_for_answers
@page = params[:page].presence || 1
question_answers
@answers_by_question_id = { @question.id => @question.answers
.by_author(current_user)
.order(:order)
.pluck(:answer) }
end
def vote_stored(answer, new_answer, token)
answer.answer = new_answer
answer.touch if answer.persisted?
answer.save!
answer.record_voter_participation(token)
@question.question_answers.visibles.where(question_id: @question).each(&:set_most_voted)
end
def store_answer
if @question.votation_type.nil?
answer = @question.answers.find_or_initialize_by(author: current_user)
else
answer = @question.votation_type.answer(current_user,
params[:answer],
positive: params[:positive])
end
answer
end
def generate_and_store_new_pair(question)
Poll::PairAnswer.generate_pair(question, current_user)
end
def question_answers
if @question.is_positive_negative?
@answers = @question.question_answers.visibles.page(@page)
else
@answers = @question.question_answers.visibles
end
end
end end

View File

@@ -20,26 +20,13 @@ class PollsController < ApplicationController
def show def show
@questions = @poll.questions.for_render.sort_for_list @questions = @poll.questions.for_render.sort_for_list
@token = poll_voter_token(@poll, current_user) @token = poll_voter_token(@poll, current_user)
@poll_questions_answers = Poll::Question::Answer.visibles @poll_questions_answers = Poll::Question::Answer.where(question: @poll.questions)
.where(question: @poll.questions)
.where.not(description: "").order(:given_order) .where.not(description: "").order(:given_order)
@answers_by_question_id = {} @answers_by_question_id = {}
poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user&.id)
@last_pair_question_answers = {} poll_answers.each do |answer|
@questions.each do |question| @answers_by_question_id[answer.question_id] = answer.answer
@answers_by_question_id[question.id] = question.answers.by_author(current_user).pluck(:answer)
if question.enum_type&.include?("answer_couples")
last_pair = question.pair_answers.by_author(current_user).first
last_pair ||= generate_and_store_new_pair(question)
@last_pair_question_answers[question.id] = last_pair
end
if question.enum_type&.include?("answer_set_closed") ||
question.enum_type&.include?("answer_set_open")
votation_answer_sets(question)
end
end end
@commentable = @poll @commentable = @poll
@@ -55,18 +42,6 @@ class PollsController < ApplicationController
private private
def votation_answer_sets(question)
if question.votation_type.votation_set_answers.by_author(current_user).empty?
question.question_answers&.sample(question.max_groups_answers).each do |question_answer|
answer = VotationSetAnswer.new(answer: question_answer.title,
votation_type: question.votation_type,
author: current_user)
question.votation_type.votation_set_answers << answer
end
!question.save
end
end
def load_poll def load_poll
@poll = Poll.where(slug: params[:id]).first || Poll.where(id: params[:id]).first @poll = Poll.where(slug: params[:id]).first || Poll.where(id: params[:id]).first
end end
@@ -74,8 +49,4 @@ class PollsController < ApplicationController
def load_active_poll def load_active_poll
@active_poll = ActivePoll.first @active_poll = ActivePoll.first
end end
def generate_and_store_new_pair(question)
Poll::PairAnswer.generate_pair(question, current_user)
end
end end

View File

@@ -77,8 +77,4 @@ module PollsHelper
def show_polls_description? def show_polls_description?
@active_poll.present? && @current_filter == "current" @active_poll.present? && @current_filter == "current"
end end
def stored_positive_negative_value(question, answer)
question.answers.find_by(author_id: current_user.id, answer: answer.title).positive
end
end end

View File

@@ -78,7 +78,7 @@ module Abilities
can [:search, :create, :index, :destroy], ::Poll::Officer can [:search, :create, :index, :destroy], ::Poll::Officer
can [:create, :destroy, :manage], ::Poll::BoothAssignment can [:create, :destroy, :manage], ::Poll::BoothAssignment
can [:create, :destroy], ::Poll::OfficerAssignment can [:create, :destroy], ::Poll::OfficerAssignment
can [:read, :create, :update, :get_options_traductions], Poll::Question can [:read, :create, :update], Poll::Question
can :destroy, Poll::Question can :destroy, Poll::Question
can :manage, SiteCustomization::Page can :manage, SiteCustomization::Page

View File

@@ -105,17 +105,12 @@ module Abilities
can :create, DirectMessage can :create, DirectMessage
can :show, DirectMessage, sender_id: user.id can :show, DirectMessage, sender_id: user.id
can [:load_answers], Poll::Question can :answer, Poll do |poll|
can [:answer], Poll do |poll|
poll.answerable_by?(user) poll.answerable_by?(user)
end end
can [:answer, :prioritized_answers], Poll::Question do |question| can :answer, Poll::Question do |question|
question.answerable_by?(user) question.answerable_by?(user)
end end
can [:create, :delete], Poll::Answer do |answer|
answer.question.answerable_by?(user)
end
end end
can [:create, :show], ProposalNotification, proposal: { author_id: user.id } can [:create, :show], ProposalNotification, proposal: { author_id: user.id }

View File

@@ -1,32 +0,0 @@
class Poll::PairAnswer < ApplicationRecord
belongs_to :question, -> { with_hidden }, inverse_of: :pair_answers
belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :poll_pair_answers
belongs_to :answer_right, class_name: "Poll::Question::Answer"
belongs_to :answer_left, class_name: "Poll::Question::Answer"
delegate :poll, :poll_id, to: :question
validates :question, presence: true
validates :author, presence: true
validates :answer_left, presence: true
validates :answer_right, presence: true
validates :answer_left, inclusion: { in: ->(a) { a.question.question_answers.visibles }},
unless: ->(a) { a.question.blank? }
validates :answer_right, inclusion: { in: ->(a) { a.question.question_answers.visibles }},
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 self.generate_pair(question, user)
answers = question.question_answers.visibles.sample(2)
question.pair_answers.by_author(user).map(&:destroy)
question.pair_answers.create(author: user, answer_left: answers[0], answer_right: answers[1])
end
def answers
[answer_left, answer_right].compact
end
end

View File

@@ -18,22 +18,14 @@ class Poll::Question < ApplicationRecord
inverse_of: :question, inverse_of: :question,
dependent: :destroy dependent: :destroy
has_many :partial_results has_many :partial_results
has_many :pair_answers
has_one :votation_type, as: :questionable, inverse_of: :questionable
belongs_to :proposal belongs_to :proposal
attr_accessor :enum_type, :max_votes, :prioritization_type
validates_translation :title, presence: true, length: { minimum: 4 } validates_translation :title, presence: true, length: { minimum: 4 }
validates :author, presence: true validates :author, presence: true
validates :poll_id, presence: true, if: proc { |question| question.poll.nil? } validates :poll_id, presence: true, if: proc { |question| question.poll.nil? }
validates_associated :votation_type
accepts_nested_attributes_for :question_answers, reject_if: :all_blank, allow_destroy: true accepts_nested_attributes_for :question_answers, reject_if: :all_blank, allow_destroy: true
delegate :enum_type, :max_votes, :prioritization_type, :max_groups_answers,
to: :votation_type, allow_nil: true
scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) } scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) }
scope :sort_for_list, -> { order("poll_questions.proposal_id IS NULL", :created_at) } scope :sort_for_list, -> { order("poll_questions.proposal_id IS NULL", :created_at) }
@@ -71,28 +63,14 @@ class Poll::Question < ApplicationRecord
end end
def answers_total_votes def answers_total_votes
question_answers.visibles.reduce(0) { |total, question_answer| total + question_answer.total_votes } question_answers.reduce(0) { |total, question_answer| total + question_answer.total_votes }
end end
def most_voted_answer_id def most_voted_answer_id
question_answers.max_by(&:total_votes).id question_answers.max_by(&:total_votes).id
end end
def answers_with_read_more?
question_answers.visibles.any? do |answer|
answer.description.present? || answer.images.any? || answer.documents.present? || answer.videos.present?
end
end
def user_can_vote(user)
max_votes.nil? || max_votes > answers.where(author: user).count
end
def is_positive_negative?
votation_type.present? && enum_type == "positive_negative_open"
end
def possible_answers def possible_answers
question_answers.visibles.joins(:translations).pluck("poll_question_answer_translations.title") question_answers.joins(:translations).pluck("poll_question_answer_translations.title")
end end
end end

View File

@@ -1,7 +1,6 @@
class Poll::Question::Answer < ApplicationRecord class Poll::Question::Answer < ApplicationRecord
include Galleryable include Galleryable
include Documentable include Documentable
paginates_per 10
translates :title, touch: true translates :title, touch: true
translates :description, touch: true translates :description, touch: true
@@ -15,10 +14,6 @@ class Poll::Question::Answer < ApplicationRecord
validates_translation :title, presence: true validates_translation :title, presence: true
validates :given_order, presence: true, uniqueness: { scope: :question_id } validates :given_order, presence: true, uniqueness: { scope: :question_id }
scope :by_author, ->(author) { where(author: author) }
scope :visibles, -> { where(hidden: false) }
def self.order_answers(ordered_array) def self.order_answers(ordered_array)
ordered_array.each_with_index do |answer_id, order| ordered_array.each_with_index do |answer_id, order|
find(answer_id).update_column(:given_order, (order + 1)) find(answer_id).update_column(:given_order, (order + 1))
@@ -30,71 +25,11 @@ class Poll::Question::Answer < ApplicationRecord
end end
def total_votes def total_votes
if !question.votation_type.present? Poll::Answer.where(question_id: question, answer: title).count +
Poll::Answer.where(question_id: question, answer: title).count + ::Poll::PartialResult.where(question: question).where(answer: title).sum(:amount)
::Poll::PartialResult.where(question: question).where(answer: title).sum(:amount)
else
case question.votation_type.enum_type
when "positive_negative_open"
total_votes_positive_negative
when "prioritized"
total_votes_prioritized
when "unique"
Poll::Answer.where(question_id: question, answer: title).count +
::Poll::PartialResult.where(question: question).where(answer: title).sum(:amount)
else
Poll::Answer.where(question_id: question, answer: title).count
end
end
end
def total_votes_positive_negative
count_positive_negative(self, true) - count_positive_negative(self, false)
end
def total_votes_prioritized
Poll::Answer.where(question_id: question, answer: title).sum(:value)
end
def most_voted?
most_voted
end end
def total_votes_percentage def total_votes_percentage
question.answers_total_votes.zero? ? 0 : (total_votes * 100.0) / question.answers_total_votes question.answers_total_votes.zero? ? 0 : (total_votes * 100.0) / question.answers_total_votes
end end
def set_most_voted
if question.enum_type.nil?
for_only_votes
else
case question.enum_type
when "positive_negative_open"
answers = question.question_answers.visibles
.map { |a| count_positive_negative(a, true) - count_positive_negative(a, false) }
is_most_voted = answers.none? { |a| a > total_votes_positive_negative }
update!(most_voted: is_most_voted)
when "prioritized"
answers = question.question_answers.visibles
.map { |a| Poll::Answer.where(question_id: a.question, answer: a.title).sum(:value) }
is_most_voted = answers.none? { |a| a > total_votes_prioritized }
update!(most_voted: is_most_voted)
else
for_only_votes
end
end
end
private
def count_positive_negative(answer, value)
Poll::Answer.where(question_id: answer.question, answer: answer.title, positive: value).count
end
def for_only_votes
answers = question.question_answers.visibles
.map { |a| Poll::Answer.where(question_id: a.question, answer: a.title).count }
is_most_voted = answers.none? { |a| a > total_votes }
update!(most_voted: is_most_voted)
end
end end

View File

@@ -81,7 +81,6 @@ class User < ApplicationRecord
inverse_of: :author inverse_of: :author
has_many :topics, foreign_key: :author_id, inverse_of: :author has_many :topics, foreign_key: :author_id, inverse_of: :author
has_many :budgets, through: :budget_rol_assignments has_many :budgets, through: :budget_rol_assignments
has_many :votation_set_answers
belongs_to :geozone belongs_to :geozone
validates :username, presence: true, if: :username_required? validates :username, presence: true, if: :username_required?

View File

@@ -1,6 +0,0 @@
class VotationSetAnswer < ApplicationRecord
belongs_to :votation_type
belongs_to :author, -> { with_hidden }, class_name: "User", inverse_of: :votation_set_answers
scope :by_author, ->(author) { where(author: author) }
end

View File

@@ -1,193 +0,0 @@
class VotationType < ApplicationRecord
belongs_to :questionable, polymorphic: true
has_many :votation_set_answers
QUESTIONABLE_TYPES = %w[Poll::Question].freeze
ENUM_TYPES_PROPS = {
unique: { enum_type: 0, open_answer: false, prioritized: false },
multiple: { enum_type: 1, open_answer: false, prioritized: false,
variables: [:max_votes] },
prioritized: { enum_type: 2, open_answer: false, prioritized: true,
variables: [:max_votes, :prioritization_type] },
positive_open: { enum_type: 3, open_answer: true, prioritized: false,
variables: [:max_votes] },
positive_negative_open: { enum_type: 4, open_answer: true, prioritized: false,
variables: [:max_votes] },
answer_couples_open: { enum_type: 5, open_answer: true, prioritized: false,
variables: [:max_votes, :display_skip_question] },
answer_couples_closed: { enum_type: 6, open_answer: false, prioritized: false,
variables: [:max_votes, :display_skip_question] },
answer_set_open: { enum_type: 7, open_answer: true, prioritized: false,
variables: [:max_votes, :max_groups_answers] },
answer_set_closed: { enum_type: 8, open_answer: false, prioritized: false,
variables: [:max_votes, :max_groups_answers] }
}.freeze
enum enum_type: ENUM_TYPES_PROPS.map { |k, v| [k, v[:enum_type]] }.to_h.freeze
enum prioritization_type: { borda: 1, dowdall: 2 }.freeze
validates :questionable, presence: true
validates :questionable_type, inclusion: { in: QUESTIONABLE_TYPES }
validates :max_votes, presence: { allow_blank: false, if: :max_votes_required? }
validates :max_groups_answers, presence: { allow_blank: false, if: :max_groups_answers_required? }
validates :prioritization_type, presence: { allow_blank: false, if: :prioritization_type_required? }
after_create :add_skip_question_answer, if: :display_skip_question?
attr_accessor :display_skip_question
def open?
open_answer
end
def prioritized?
prioritized
end
def answer(user, answer, options = {})
result = nil
votes = questionable.answers
if votable_question?(answer)
case enum_type
when "unique"
result = votes.find_or_initialize_by(author: user)
when "multiple", "positive_open"
if check_max_votes(user, votes)
result = votes.find_or_initialize_by(author: user, answer: answer)
end
when "prioritized"
result = votes.find_by(author: user, answer: answer)
if result.nil?
if check_max_votes(user, votes)
if votes.by_author(user.id).empty?
order = 1
else
order = votes.by_author(user.id).order(:order).last.order + 1
end
result = votes.find_or_initialize_by(author: user,
answer: answer,
order: order)
end
else
!result.update(order: options[:order])
end
when "positive_negative_open"
result = votes.by_author(user.id).find_by(answer: answer)
if result.nil?
if check_max_votes(user, votes)
result = votes.create!(author: user,
answer: answer,
positive: options[:positive])
end
else
!result.update(positive: options[:positive])
end
when "answer_couples_closed", "answer_couples_open"
if check_max_votes(user, votes)
result = votes.create!(
answer: answer,
author: user,
positive: true,
order: votes&.by_author(user.id).count + 1
)
end
Poll::PairAnswer.generate_pair(questionable, user)
when "answer_set_open", "answer_set_closed"
if check_max_votes(user, votes) && answer_in_set?(answer, user)
result = votes&.find_or_initialize_by(author: user, answer: answer)
end
end
end
result
end
def create_question_answer(answer, hidden = false)
return if questionable.question_answers.where(title: answer).any?
questionable.question_answers
.create!(
title: answer,
given_order: questionable.question_answers.maximum(:given_order).to_i + 1,
hidden: hidden
)
true
end
def votable_question?(answer)
questionable.question_answers.where(title: answer).present?
end
def self.build_by_type(questionable, params)
attributes = { questionable: questionable }
enum_type = self.enum_types.key(params[:enum_type].to_i)
enum_type_props = enum_properties(enum_type)
attributes.merge!(enum_type_props.except(:variables))
enum_type_props[:variables]&.each do |property|
attributes[property] = params[property]
end
attributes[:prioritization_type] = attributes[:prioritization_type]&.to_i
new(attributes)
end
def self.create_by_type(questionable, params)
votation_type = build_by_type(questionable, params)
votation_type.save!
end
def update_priorized_values(user)
case prioritization_type
when "borda"
questionable.answers.by_author(user).order(:order).each_with_index do |answer, i|
value = max_votes - i
!answer.update(value: value)
end
when "dowdall"
questionable.answers.by_author(user).order(:order).each_with_index do |answer, i|
value = 60 / (i + 1)
!answer.update(value: value)
end
end
end
private
def answer_in_set?(answer, user)
votation_set_answers&.by_author(user)&.pluck(:answer).include?(answer)
end
def check_max_votes(user, votes)
max_votes > votes&.by_author(user.id).count
end
def self.enum_properties(enum_type)
ENUM_TYPES_PROPS[enum_type&.to_sym] || ENUM_TYPES_PROPS[:unique]
end
def self.enum_properties_variables(enum_type)
enum_properties(enum_type)&.dig(:variables)
end
def max_votes_required?
VotationType.enum_properties_variables(self.enum_type)&.include?(:max_votes)
end
def max_groups_answers_required?
VotationType.enum_properties_variables(self.enum_type)&.include?(:max_groups_answers)
end
def prioritization_type_required?
VotationType.enum_properties_variables(self.enum_type)&.include?(:prioritization_type)
end
def display_skip_question?
VotationType.enum_properties_variables(self.enum_type)&.include?(:display_skip_question)
end
def add_skip_question_answer
create_question_answer("I can't decided", true)
end
end

View File

@@ -31,39 +31,6 @@
<% end %> <% end %>
</div> </div>
<div class="row">
<% if !@question.persisted? %>
<%= fields_for :votation_type, @question.votation_type || @question.build_votation_type do |votation_f| %>
<div class="small-12 medium-6">
<%= votation_f.select :enum_type,
options_for_select(VotationType.enum_types.map { |k, v| [t(k, scope: :enum_type), v] },
params.dig(:votation_type, :enum_type)), default: 0,
disabled: @question.persisted? %>
</div>
<div class="info-type">
<span class="js-description_text">
<%= t("polls.index.descriptions.unique") %>
</span>
<div class="small-12 medium-6 margin-description js-max_votes hidden ">
<%= votation_f.number_field :max_votes, min: 1, max: 999,
value: params.dig(:votation_type, :max_votes) %>
</div>
<div class="small-12 medium-6 js-prioritization_type hidden">
<%= votation_f.select :prioritization_type,
options_for_select(VotationType.prioritization_types.map { |k, v| [t(k, scope: :prioritization_type), v] },
params.dig(:votation_type, :prioritization_type)), default: 0,
disabled: @question.persisted? %>
</div>
<div class="small-12 medium-6 js-max_group_votes hidden">
<%= votation_f.number_field :max_groups_answers, min: 1, max: 999,
value: params.dig(:votation_type, :max_groups_answers) %>
</div>
</div>
<% end %>
<% end %>
</div>
<div class="row"> <div class="row">
<div class="small-12 medium-4 large-2 margin-top column"> <div class="small-12 medium-4 large-2 margin-top column">
<%= f.submit(class: "button success expanded", value: t("shared.save")) %> <%= f.submit(class: "button success expanded", value: t("shared.save")) %>

View File

@@ -26,35 +26,6 @@
<%= link_to @question.proposal.title, proposal_path(@question.proposal) %> <%= link_to @question.proposal.title, proposal_path(@question.proposal) %>
</p> </p>
<% end %> <% end %>
<% unless @question.votation_type.nil? %>
<p>
<strong><%= t("question.votation_type") %></strong>
<br>
<%= t("enum_type.#{@question.votation_type.enum_type}") %>
</p>
<% if !@question.votation_type.max_votes.nil? %>
<p>
<strong><%= VotationType.human_attribute_name(:max_votes) %></strong>
<br>
<%= @question.votation_type.max_votes %>
</p>
<% end %>
<% if !@question.votation_type.prioritization_type.nil? %>
<p>
<strong><%= VotationType.human_attribute_name(:prioritization_type) %></strong>
<br>
<%= t("prioritization_type.#{@question.votation_type.prioritization_type}") %>
</p>
<% end %>
<% if !@question.votation_type.max_groups_answers.nil? %>
<p>
<strong><%= VotationType.human_attribute_name(:max_groups_answers) %></strong>
<br>
<%= @question.votation_type.max_groups_answers %>
</p>
<% end %>
<% end %>
</div> </div>
</div> </div>

View File

@@ -1,40 +0,0 @@
<div class="polls-results-stats">
<div class="row margin">
<div class="small-12 medium-3 column">
<p><strong><%= t("polls.show.results.title") %></strong></p>
<ul class="menu vertical">
<%- @poll.questions.each do |question| %>
<li><%= link_to question.title, "##{question.title.parameterize}" %></li>
<% end %>
</ul>
</div>
<div class="small-12 medium-9 column">
<%- @poll.questions.each do |question| %>
<h3 id="<%= question.title.parameterize %>"><%= question.title %></h3>
<table id="question_<%= question.id %>_results_table">
<tbody>
<%- question.question_answers.visibles.each do |answer| %>
<tr scope="col" <%= answer.most_voted? ? "class=win" : "" %>>
<td>
<% if answer.most_voted %>
<span class="show-for-sr"><%= t("polls.show.results.most_voted_answer") %></span>
<% end %>
<%= answer.title %>
</td>
<td id="answer_<%= answer.id %>_result" <%= answer.most_voted? ? "class=win" : "" %>>
<%= answer.total_votes %>
<% unless question.enum_type == "positive_negative_open" %>
(<%= answer.total_votes_percentage.round(2) %>%)
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
</div>
</div>

View File

@@ -11,14 +11,10 @@
</div> </div>
<% end %> <% end %>
<% if @poll.questions.any? { |question| question.votation_type.present? } %> <% if @partial_results.present? %>
<%= render "votation_types_results" %> <%= render "recount", resource: @poll %>
<% else %> <%= render "result" %>
<% if @partial_results.present? %> <%= render "results_by_booth" %>
<%= render "recount", resource: @poll %>
<%= render "result" %>
<%= render "results_by_booth" %>
<% end %>
<% end %> <% end %>
<% if @poll.voters.any? %> <% if @poll.voters.any? %>

View File

@@ -1,22 +1,33 @@
<% if question.votation_type.nil? %> <div class="poll-question-answers">
<%= render "polls/questions/answers_unique", question: question, answers: answers, token: token %> <% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<% else %> <% question.question_answers.each do |answer| %>
<% case question.votation_type.enum_type %> <% if @answers_by_question_id[question.id] == answer.title &&
<% when "unique" %> (!voted_before_sign_in(question) ||
<%= render "polls/questions/answers_unique", question: question, answers: answers, token: token %> question.poll.voted_in_booth?(current_user)) %>
<% when "multiple", "positive_open" %> <span class="button answered"
<%= render "polls/questions/answers_multiple", question: question, answers: answers, token: token %> title="<%= t("poll_questions.show.voted", answer: answer.title) %>">
<% when "positive_negative_open" %> <%= answer.title %>
<%= render "polls/questions/answers_positive_negative", question: question, answers: answers, token: token, page: page %> </span>
<% when "answer_couples_closed" %> <% else %>
<%= render "polls/questions/answers_couples", answers_open: false, question: question, token: token %> <%= link_to answer.title,
<% when "answer_couples_open" %> answer_question_path(question, answer: answer.title, token: token),
<%= render "polls/questions/answers_couples", answers_open: true, question: question, token: token %> method: :post,
<% when "answer_set_closed", "answer_set_open" %> remote: true,
<%= render "polls/questions/answers_set", question: question, token: token, answers: question.votation_type.votation_set_answers.by_author(current_user) %> title: t("poll_questions.show.vote_answer", answer: answer.title),
<% when "prioritized" %> class: "button secondary hollow js-question-answer" %>
<%= render "polls/questions/answers_prioritized", answers_open: false, question: question, answers: answers, token: token %> <% end %>
<% end %>
<% elsif !user_signed_in? %>
<% question.question_answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% question.question_answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %> <% else %>
<%= render "polls/questions/answers_unique", question: question, answers: answers, token: token %> <% question.question_answers.order(id: :desc).each do |answer| %>
<span class="button secondary hollow disabled"><%= answer.title %></span>
<% end %>
<% end %> <% end %>
<% end %> </div>

View File

@@ -1,39 +0,0 @@
<div class="poll-question-answers">
<% if can?(:answer, question) && question.user_can_vote(current_user) %>
<div class="small-12 medium-12 text-center">
<% @last_pair_question_answers.dig(question.id)&.answers&.each do |answer| %>
<div class="small-12 medium-5 inline-block">
<%= link_to answer.title,
answer_question_path(question, answer: answer.title, token: token),
method: :post,
remote: true,
title: t("poll_questions.show.vote_answer", answer: answer.title),
class: "button secondary hollow js-question-answer" %>
</div>
<% end %>
</div>
<div class="small-12 medium-12 text-center">
<%= link_to "I can't decide",
answer_question_path(question, answer: "I can't decided", token: token),
method: :post,
remote: true,
title: "I can't decide",
class: "button secondary hollow js-question-answer" %>
</div>
<% if answers_open %>
<%= render "/polls/questions/new_answer", question: question, token: token %>
<% end %>
<% elsif !user_signed_in? %>
<% question.question_answers.visibles.order(id: :desc).each do |answer| %>
<%= link_to answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% question.question_answers.visibles.order(id: :desc).each do |answer| %>
<%= link_to answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<%= t("polls.index.max_votes_reached") %>
<% end %>
</div>

View File

@@ -1,36 +0,0 @@
<div class="poll-question-answers">
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<% answers&.each do |answer| %>
<% if @answers_by_question_id[question.id].include?(answer.title) %>
<%= link_to answer.title,
answer_question_path(question, answer: answer.title, token: token),
method: :delete,
remote: true,
title: t("poll_questions.show.voted", answer: answer.title),
class: "button answered expand" %>
<% else %>
<%= link_to answer.title,
answer_question_path(question, answer: answer.title, token: token),
method: :post,
remote: true,
title: t("poll_questions.show.vote_answer", answer: answer.title),
class: "button secondary hollow js-question-answer" %>
<% end %>
<% end %>
<% if question.enum_type == "positive_open" %>
<%= render "/polls/questions/new_answer", question: question, token: token %>
<% end %>
<% elsif !user_signed_in? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<% answers.order(id: :desc).each do |answer| %>
<span class="button secondary hollow disabled"><%= answer.title %></span>
<% end %>
<% end %>
</div>

View File

@@ -1,55 +0,0 @@
<div class="poll-question-answers">
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<table class="voting-list">
<% answers&.each do |answer| %>
<tr class="answer medium-12 inline-block" style="border-bottom: 1px solid lightslategrey;">
<td class="title-answer medium-9 inline-block">
<span class="inline-block"><%= answer.title %></span>
</td>
<td class="votes inline-block vote-align">
<div class="in-favor inline-block">
<% if @answers_by_question_id[question.id].include?(answer.title) &&
stored_positive_negative_value(question, answer) %>
<%= render "polls/questions/like_dislike", question: question,
answer: answer, method: "delete", positive: true,
token: token, active: true, page: page %>
<% else %>
<%= render "polls/questions/like_dislike", question: question,
answer: answer, method: "post", positive: true,
token: token, active: false, page: page %>
<% end %>
</div>
<div class="against inline-block">
<% if @answers_by_question_id[question.id].include?(answer.title) &&
!stored_positive_negative_value(question, answer) %>
<%= render "polls/questions/like_dislike", question: question,
answer: answer, method: "delete", positive: false,
token: token, active: true, page: page %>
<% else %>
<%= render "polls/questions/like_dislike", question: question,
answer: answer, method: "post", positive: false,
token: token, active: false, page: page %>
<% end %>
</div>
</td>
</tr>
<% end %>
</table>
<%= paginate answers, params: { controller: "polls/questions", action: :load_answers, id: question }, remote: true %>
<%= render "/polls/questions/new_answer", question: question, token: token %>
<% elsif !user_signed_in? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% answers.visibles.order(id: :desc).each do |answer| %>
<%= link_to answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<% answers.order(id: :desc).each do |answer| %>
<span class="button secondary hollow disabled"><%= answer.title %></span>
<% end %>
<% end %>
</div>

View File

@@ -1,44 +0,0 @@
<div class="poll-question-answers">
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<ol type="1" class="sortable-priotirized-votation" data-js-url="<%= prioritized_answers_question_path(question, token: token) %>">
<% @answers_by_question_id[question.id].each do |answer| %>
<li data-answer-id="<%= answer %>">
<span class="button answered expanded"
title="<%= t("poll_questions.show.voted", answer: answer) %>">
<%= answer %>
</span>
</li>
<% end %>
</ol>
<% answers&.each do |answer| %>
<% if @answers_by_question_id[question.id].include?(answer.title) %>
<%= link_to answer.title,
answer_question_path(question, answer: answer.title, token: token),
method: :delete,
remote: true,
title: t("poll_questions.show.voted", answer: answer.title),
class: "button answered expand" %>
<% else %>
<%= link_to answer.title,
answer_question_path(question, answer: answer.title, token: token),
method: :post,
remote: true,
title: t("poll_questions.show.vote_answer", answer: answer.title),
class: "button secondary hollow js-question-answer" %>
<% end %>
<% end %>
<% elsif !user_signed_in? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<% answers.order(id: :desc).each do |answer| %>
<span class="button secondary hollow disabled"><%= answer.title %></span>
<% end %>
<% end %>
</div>

View File

@@ -1,37 +0,0 @@
<div class="poll-question-answers">
<% if can?(:answer, question) %>
<% answers.each do |answer| %>
<% if @answers_by_question_id[question.id].include?(answer.answer) %>
<%= link_to answer.answer,
answer_question_path(question, answer: answer.answer, token: token),
method: :delete,
remote: true,
title: t("poll_questions.show.voted", answer: answer.answer),
class: "button answered" %>
<% else %>
<%= link_to answer.answer,
answer_question_path(question, answer: answer.answer, token: token),
method: :post,
remote: true,
title: t("poll_questions.show.vote_answer", answer: answer.answer),
class: "button secondary hollow js-question-answer" %>
<% end %>
<% end %>
<% if question.enum_type == "answer_set_open" %>
<%= render "/polls/questions/new_answer", question: question, token: token %>
<%= flash[:notice] %>
<% end %>
<% elsif !user_signed_in? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.answer, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.answer, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<% answers.order(id: :desc).each do |answer| %>
<span class="button secondary hollow disabled"><%= answer.answer %></span>
<% end %>
<% end %>
</div>

View File

@@ -1,33 +0,0 @@
<div class="poll-question-answers">
<% if can?(:answer, question) && !question.poll.voted_in_booth?(current_user) %>
<% answers&.each do |answer| %>
<% if @answers_by_question_id[question.id].include?(answer.title) &&
(!voted_before_sign_in(question) ||
question.poll.voted_in_booth?(current_user)) %>
<span class="button answered"
title="<%= t("poll_questions.show.voted", answer: answer.title) %>">
<%= answer.title %>
</span>
<% else %>
<%= link_to answer.title,
answer_question_path(question, answer: answer.title, token: token),
method: :post,
remote: true,
title: t("poll_questions.show.vote_answer", answer: answer.title),
class: "button secondary hollow js-question-answer" %>
<% end %>
<% end %>
<% elsif !user_signed_in? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, new_user_session_path, class: "button secondary hollow" %>
<% end %>
<% elsif !current_user.level_two_or_three_verified? %>
<% answers.order(id: :desc).each do |answer| %>
<%= link_to answer.title, verification_path, class: "button secondary hollow" %>
<% end %>
<% else %>
<% answers.order(id: :desc).each do |answer| %>
<span class="button secondary hollow disabled"><%= answer.title %></span>
<% end %>
<% end %>
</div>

View File

@@ -1,19 +0,0 @@
<%= link_to answer_question_path(question, answer: answer.title, positive: positive, token: token, page: page),
method: method.to_sym,
remote: true,
title: t("poll_questions.show.vote_answer", answer: answer.title),
class: "expand js-question-answer" do %>
<% if positive %>
<% if active %>
<span class="icon-like active-like"></span>
<% else %>
<span class="icon-like"></span>
<% end %>
<% else %>
<% if active %>
<span class="icon-unlike active-unlike"></span>
<% else %>
<span class="icon-unlike"></span>
<% end %>
<% end %>
<% end %>

View File

@@ -1,6 +0,0 @@
<%= form_tag(create_answer_question_path(question, token: token), method: :post, remote: true) do %>
<% id = "your_answer_#{SecureRandom.hex}" %>
<%= label_tag :answer, t("poll_questions.show.your_answer"), for: id %>
<%= text_field_tag :answer, nil, class: "medium-10", id: id %>
<%= submit_tag t("poll_questions.show.add_answer"), class: "button success" %>
<% end %>

View File

@@ -3,35 +3,7 @@
<%= question.title %> <%= question.title %>
</h3> </h3>
<% unless question.votation_type.nil? %>
<strong>
<%= t("poll_questions.description.#{question.enum_type}",
maximum: question.votation_type.max_votes,
system: question.votation_type.prioritization_type) %>
</strong>
<% end %>
<div id="<%= dom_id(question) %>_answers" class="padding"> <div id="<%= dom_id(question) %>_answers" class="padding">
<% answers = question.is_positive_negative? ? question.question_answers.visibles.page(1) : question.question_answers.visibles %> <%= render "polls/questions/answers", question: question, token: token %>
<%= render "polls/questions/answers", question: question, token: token, answers: answers, page: 1 %>
</div> </div>
<% if question.answers_with_read_more? %>
<div class="poll_question_read_more">
<p><%= t("poll_questions.read_more_about") %></p>
<p>
<% first = true %>
<% question.question_answers&.visibles&.each do |answer| %>
<% if answer.description.present? || answer.images.any? ||
answer.documents.present? || answer.videos.present? %>
<% unless first %>
<span>,&nbsp;</span>
<% end %>
<% first = false if first %>
<%= link_to answer.title, "#answer_description_#{answer.id}" %>
<% end %>
<% end %>
</p>
</div>
<% end %>
</div> </div>

View File

@@ -1,3 +1,2 @@
<% token = poll_voter_token(@question.poll, current_user) %> <% token = poll_voter_token(@question.poll, current_user) %>
$("#<%= dom_id(@question) %>_answers").html("<%= j render("polls/questions/answers", question: @question, answers: @answers, token: token, page: @page) %>"); $("#<%= dom_id(@question) %>_answers").html("<%= j render("polls/questions/answers", question: @question, token: token) %>");
App.Sortable.initialize();

View File

@@ -1,5 +1,4 @@
<% provide :title do %><%= @poll.name %> <% provide :title do %><%= @poll.name %><% end %>
<% end %>
<div class="polls-results-stats"> <div class="polls-results-stats">
<%= render "poll_header" %> <%= render "poll_header" %>
@@ -18,29 +17,33 @@
<div class="small-12 medium-9 column" data-equalizer-watch> <div class="small-12 medium-9 column" data-equalizer-watch>
<%- @poll.questions.each do |question| %> <%- @poll.questions.each do |question| %>
<% most_voted_answer_id = question.most_voted_answer_id %>
<h3 id="<%= question.title.parameterize %>"><%= question.title %></h3> <h3 id="<%= question.title.parameterize %>"><%= question.title %></h3>
<table id="question_<%= question.id %>_results_table"> <table id="question_<%= question.id %>_results_table">
<tbody> <thead>
<%- question.question_answers.visibles.each do |answer| %> <tr>
<tr scope="col" <%= answer.most_voted? ? "class=win" : "" %>> <%- question.question_answers.each do |answer| %>
<td> <th scope="col" <%= answer.id == most_voted_answer_id ? "class=win" : "" %>>
<% if answer.most_voted %> <% if answer.id == most_voted_answer_id %>
<span class="show-for-sr"><%= t("polls.show.results.most_voted_answer") %></span> <span class="show-for-sr"><%= t("polls.show.results.most_voted_answer") %></span>
<% end %> <% end %>
<%= answer.title %> <%= answer.title %>
</td> </th>
<td id="answer_<%= answer.id %>_result" <%= answer.most_voted? ? "class=win" : "" %>> <% end %>
<%= answer.total_votes %> </tr>
<% unless question.enum_type == "positive_negative_open" || question.enum_type == "prioritized" %> </thead>
(<%= answer.total_votes_percentage.round(2) %>%) <tbody>
<% end %> <tr>
</td> <%- question.question_answers.each do |answer| %>
<td id="answer_<%= answer.id %>_result" <%= answer.id == most_voted_answer_id ? "class=win" : "" %>>
<%= answer.total_votes %>
(<%= answer.total_votes_percentage.round(2) %>%)
</td>
<% end %>
</tr> </tr>
<% end %>
</tbody> </tbody>
</table> </table>
<% end %> <% end %>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -55,83 +55,71 @@
<div id="poll_more_info_answers" class="expanded poll-more-info-answers"> <div id="poll_more_info_answers" class="expanded poll-more-info-answers">
<div class="row padding"> <div class="row padding">
<% @questions.each do |question| %> <% @poll_questions_answers.each do |answer| %>
<% if question.answers_with_read_more? %> <div class="small-12 medium-6 column end answer <%= cycle("first", "") %>" id="answer_<%= answer.id %>">
<div class="row question-divider"> <% if answer.description.present? %>
<h2><%= question.title %></h2> <h3><%= answer.title %></h3>
<% question.question_answers.visibles.each do |answer| %> <% end %>
<% if answer.description.present? || answer.images.any? || answer.documents.present? || answer.videos.present? %>
<div class="small-12 medium-6 column margin-top margin-bottom" id="answer_<%= answer.id %>">
<h3><%= answer.title %></h3>
<div class="margin-top">
<div id="answer_description_<%= answer.id %>"
class="answer-description short answer-left-divider" data-toggler="short">
<% if answer.description.present? %>
<%= wysiwyg(answer.description) %>
<% end %>
<% if answer.images.any? %> <% if answer.images.any? %>
<div class="margin-top"> <%= render "gallery", answer: answer %>
<%= render "gallery", answer: answer %> <% end %>
</div>
<% end %>
<% if answer.documents.present? %> <% if answer.description.present? %>
<div class="document-link"> <div class="margin-top">
<p> <div id="answer_description_<%= answer.id %>" class="answer-description short" data-toggler="short">
<span class="icon-document"></span>&nbsp; <%= wysiwyg(answer.description) %>
<strong><%= t("polls.show.documents") %></strong> </div>
</p> <div class="margin">
<% answer.documents.each do |document| %> <a id="read_more_<%= answer.id %>"
<%= link_to document.title, data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>"
document.attachment.url, data-toggler="hide">
target: "_blank", <%= t("polls.show.read_more", answer: answer.title) %>
rel: "nofollow" %> </a>
<br> <a id="read_less_<%= answer.id %>"
<% end %> data-toggle="answer_description_<%= answer.id %> read_more_<%= answer.id %> read_less_<%= answer.id %>"
</div> data-toggler="hide"
<% end %> class="hide">
<%= t("polls.show.read_less", answer: answer.title) %>
</a>
</div>
</div>
<% end %>
<% if answer.videos.present? %> <% if answer.documents.present? %>
<div class="video-link"> <div class="document-link">
<p> <p>
<span class="icon-video"></span>&nbsp; <span class="icon-document"></span>&nbsp;
<strong><%= t("polls.show.videos") %></strong> <strong><%= t("polls.show.documents") %></strong>
</p> </p>
<% answer.videos.each do |video| %> <% answer.documents.each do |document| %>
<%= link_to video.title, <%= link_to document.title,
video.url, document.attachment.url,
target: "_blank", target: "_blank",
rel: "nofollow" %> rel: "nofollow" %><br>
<br>
<% end %>
</div>
<% end %>
</div>
<div class="margin-top margin-bottom">
<a id="read_more_<%= answer.id %>"
data-toggle="answer_description_<%= answer.id %>
read_more_<%= answer.id %> read_less_<%= answer.id %>"
data-toggler="hide">
<%= t("polls.show.read_more", answer: answer.title) %>
</a>
<a id="read_less_<%= answer.id %>"
data-toggle="answer_description_<%= answer.id %>
read_more_<%= answer.id %> read_less_<%= answer.id %>"
data-toggler="hide" class="hide">
<%= t("polls.show.read_less", answer: answer.title) %>
</a>
</div>
</div>
</div>
<% end %> <% end %>
<% end %> </div>
</div> <% end %>
<% end %>
<% if answer.videos.present? %>
<div class="video-link">
<p>
<span class="icon-video"></span>&nbsp;
<strong><%= t("polls.show.videos") %></strong>
</p>
<% answer.videos.each do |video| %>
<%= link_to video.title,
video.url,
target: "_blank",
rel: "nofollow" %><br>
<% end %>
</div>
<% end %>
</div>
<% end %> <% end %>
</div> </div>
</div> </div>
<div class="tabs-content" data-tabs-content="polls_tabs"> <div class="tabs-content" data-tabs-content="polls_tabs">

View File

@@ -333,11 +333,6 @@ en:
topic: topic:
title: "Title" title: "Title"
description: "Initial text" description: "Initial text"
votation_type:
enum_type: "Votation type"
max_groups_answers: "Maximum number of answers in the set"
max_votes: "Maximum number of votes"
prioritization_type: "Prioritization type"
banner: banner:
background_color: Background color background_color: Background color
font_color: Font color font_color: Font color

View File

@@ -542,7 +542,6 @@ en:
index: index:
title: Polls title: Polls
create: Create poll create: Create poll
succesfull: Answer added succesfully
count: count:
one: You have created %{count} poll. one: You have created %{count} poll.
other: You have created %{count} polls. other: You have created %{count} polls.
@@ -634,17 +633,6 @@ en:
title: Help about voting title: Help about voting
description: Citizens' polls are a participatory mechanism by which citizens with voting rights can make direct decisions description: Citizens' polls are a participatory mechanism by which citizens with voting rights can make direct decisions
no_polls: "There are no open votings." no_polls: "There are no open votings."
max_votes_reached: "You have already made the maximum number of votes. Thank you very much for participating"
descriptions:
unique: It's only possible to answer one time to the question.
multiple: Allows to choose multiple answers. It's possible to set the maximum number of answers.
prioritized: Allows to choose more than one answer and they will be prioritized. It's possible to set the maximum number of answers chosen and the answer count type.
positive_open: Allows to vote positively a maximum number of times to questions. It's possible to set the maximum number of answers and add other answers.
positive_negative_open: Allows to vote positively and negatively a maximum number of times to questions. It's possible to set the maximum number of answers and add other answers.
answer_couples_open: Allows to vote a maximum number of times to couples of possible answers. It's possible to set the maximum number of couples and add other answers.
answer_couples_closed: Allows to vote a maximum number of times to couples of possible answers. It's possible to set the maximum number of couples and it's not possible to add other answers.
answer_set_open: Allows to vote a maximum number of answers to a group of them. It's possible to set the maximum number of answers, the size of the group and add other answers.
answer_set_closed: Allows to vote a maximum number of answers to a group of them. It's possible to set the maximum number of answers and the size of the group.
show: show:
already_voted_in_booth: "You have already participated in a physical booth. You can not participate again." already_voted_in_booth: "You have already participated in a physical booth. You can not participate again."
already_voted_in_web: "You have already participated in this poll. If you vote again it will be overwritten." already_voted_in_web: "You have already participated in this poll. If you vote again it will be overwritten."
@@ -683,19 +671,6 @@ en:
show: show:
vote_answer: "Vote %{answer}" vote_answer: "Vote %{answer}"
voted: "You have voted %{answer}" voted: "You have voted %{answer}"
your_answer: "You can add your own answer"
add_answer: "Add answer"
description:
multiple: "You can select a maximum of %{maximum} answers."
positive_negative_open: "You can vote positive or negative a maximum of %{maximum} answers. And you can add your own answers."
answer_couples_open: "Choose an option from the following pair. You can choose a maximum of %{maximum} answers."
answer_couples_closed: "Choose an option from the following pair. You can choose a maximum of %{maximum} answers."
answer_set_open: "You can choose a maximum of %{maximum} answers."
answer_set_closed: "You can choose a maximum of %{maximum} answers."
prioritized: "You can select a maximum of %{maximum} answers. This question will use the %{system} system for count."
positive_open: "You can select a maximum of %{maximum} answers and add your own answers."
unique: ""
read_more_about: "Read more about:"
proposal_notifications: proposal_notifications:
new: new:
title: "Send message" title: "Send message"
@@ -998,21 +973,6 @@ en:
surveys: Surveys surveys: Surveys
poll: poll:
take_part: Take part from %{from} to %{to} take_part: Take part from %{from} to %{to}
question:
votation_type: Votation type
enum_type:
unique: Unique answer, closed
multiple: Multiple answers, closed
prioritized: Multiple prioritized answer, closed
positive_open: Votable positive, open
positive_negative_open: Votable positive and negative, open
answer_couples_open: Couples of answers, open
answer_couples_closed: Couples of answers, closed
answer_set_open: Set of answers, open
answer_set_closed: Set of answers, closed
prioritization_type:
borda: Borda votation
dowdall: Dowdall votation
remote_translations: remote_translations:
text: The content of this page is not available in your language text: The content of this page is not available in your language
all_remote_translations_enqueued_text: In a short period of time refreshing the page you will be able to see all the content in your language. all_remote_translations_enqueued_text: In a short period of time refreshing the page you will be able to see all the content in your language.

View File

@@ -335,11 +335,6 @@ es:
topic: topic:
title: "Título" title: "Título"
description: "Texto inicial" description: "Texto inicial"
votation_type:
enum_type: "Tipo de votación"
max_groups_answers: "Número máximo de respuestas en el conjunto"
max_votes: "Número máximo de votos"
prioritization_type: "Tipo de priorizacion"
banner: banner:
background_color: Color del fondo background_color: Color del fondo
font_color: Color del texto font_color: Color del texto

View File

@@ -542,7 +542,6 @@ es:
index: index:
title: Encuestas title: Encuestas
create: Crear encuesta create: Crear encuesta
succesfull: Respuesta añadida correctamente.
count: count:
one: Has creado %{count} encuesta. one: Has creado %{count} encuesta.
other: Has creado %{count} encuestas. other: Has creado %{count} encuestas.
@@ -632,17 +631,6 @@ es:
title: Ayuda sobre las votaciones title: Ayuda sobre las votaciones
description: Las votaciones ciudadanas son un mecanismo de participación por el que la ciudadanía con derecho a voto puede tomar decisiones de forma directa. description: Las votaciones ciudadanas son un mecanismo de participación por el que la ciudadanía con derecho a voto puede tomar decisiones de forma directa.
no_polls: "No hay votaciones abiertas." no_polls: "No hay votaciones abiertas."
max_votes_reached: "Ya has realizado el número máximo de votos. Muchas gracias por participar"
descriptions:
unique: Solo se puede responder a la pregunta con una única respuesta.
multiple: Permite elegir más de una respuesta. Se puede elegir el número máximo de respuestas.
prioritized: Permite elegir mas de una respuesta, que a su vez se podran ordenar por prioridad. Se puede elegir el número máximo de respuestas y que tipo de recuento se utilizará en la priorización.
positive_open: Permite votar positivamente a un número máximo de respuestas. Se puede elegir el número máximo y los usuarios podran añadir resuestas.
positive_negative_open: Permite votar positiva y negativamente a un máximo de respuestas. Se puede elegir el número máximo y los usuarios podran añadir resuestas.
answer_couples_open: Permite votar a un número maximo de pares de respuestas. Se puede elegir el número maximo de pares y los usuarios podran añadir respuestas.
answer_couples_closed: Permite votar a un número maximo de pares de respuestas. Se puede elegir el número maximo de pares y los usuarios NO podran añadir respuestas.
answer_set_open: Permite votar un número máximo de respuestas en un conjunto de ellas. Se puede elegir el numero máximo de respuestas y el número de respuestas que hay en el conjunto. Los usuarios podran añadir respuestas.
answer_set_closed: Permite votar un número máximo de respuestas en un conjunto de ellas. Se puede elegir el numero máximo de respuestas y el número de respuestas que hay en el conjunto.
show: show:
already_voted_in_booth: "Ya has participado en esta votación en urnas presenciales, no puedes volver a participar." already_voted_in_booth: "Ya has participado en esta votación en urnas presenciales, no puedes volver a participar."
already_voted_in_web: "Ya has participado en esta votación. Si vuelves a votar se sobreescribirá tu resultado anterior." already_voted_in_web: "Ya has participado en esta votación. Si vuelves a votar se sobreescribirá tu resultado anterior."
@@ -681,20 +669,6 @@ es:
show: show:
vote_answer: "Votar %{answer}" vote_answer: "Votar %{answer}"
voted: "Has votado %{answer}" voted: "Has votado %{answer}"
your_answer: "Puedes añadir tu propia respuesta"
add_answer: "Añadir respuesta"
description:
multiple: "Puedes seleccionar un máximo de %{maximum} respuestas."
positive_negative_open: "Puedes votar, positiva o negativamente, un máximo de %{maximum} respuestas. Puedes añadir tus propias respuestas."
multiple: "Puedes seleccionar un máximo de %{maximum} respuestas"
answer_couples_open: "Elige una opción entre el siguiente par. Puedes elegir un máximo de %{maximum} respuestas"
answer_couples_closed: "Elige una opción entre el siguiente par. Puedes elegir un máximo de %{maximum} respuestas"
answer_set_open: "Puede elegir un máximo de %{maximum} respuestas."
answer_set_closed: "Puede elegir un máximo de %{maximum} respuestas."
prioritized: "Puedes seleccionar un máximo de %{maximum} respuestas. Esta pregunta utilizara el método %{system} para el recuento."
positive_open: "Puedes seleccionar un máximo de %{maximum} respuestas y añadir tus propias respuestas."
unique: ""
read_more_about: "Leer más:"
proposal_notifications: proposal_notifications:
new: new:
title: "Enviar mensaje" title: "Enviar mensaje"
@@ -997,21 +971,6 @@ es:
surveys: Encuestas surveys: Encuestas
poll: poll:
take_part: Participa del %{from} al %{to} take_part: Participa del %{from} al %{to}
question:
votation_type: Tipo de votación
enum_type:
unique: Respuesta única, cerrada
multiple: Respuesta múltiple, cerrada
prioritized: Respuesta múltiple priorizada, cerrada
positive_open: Respuestas votables positivamente, abiertas
positive_negative_open: Respuestas votables positiva y negativamente, abiertas
answer_couples_open: Respuestas a pares, abiertas
answer_couples_closed: Respuestas a pares, cerradas
answer_set_open: Conjunto de respuestas, abiertas
answer_set_closed: Conjunto de respuestas, cerradas
prioritization_type:
borda: Votación con recuento Borda
dowdall: Votación con recuento Dowdall
remote_translations: remote_translations:
text: El contenido de esta página no está disponible en tu idioma text: El contenido de esta página no está disponible en tu idioma
all_remote_translations_enqueued_text: "En un breve periodo de tiempo refrescando la página podrá ver todo el contenido en su idioma" all_remote_translations_enqueued_text: "En un breve periodo de tiempo refrescando la página podrá ver todo el contenido en su idioma"

View File

@@ -162,7 +162,6 @@ namespace :admin do
end end
resource :active_polls, only: [:create, :edit, :update] resource :active_polls, only: [:create, :edit, :update]
get :get_options_traductions, controller: "questions"
end end
resources :verifications, controller: :verifications, only: :index do resources :verifications, controller: :verifications, only: :index do

View File

@@ -5,12 +5,6 @@ resources :polls, only: [:show, :index] do
end end
resources :questions, controller: "polls/questions", shallow: true do resources :questions, controller: "polls/questions", shallow: true do
member do post :answer, on: :member
post :answer
post :prioritized_answers
delete :answer, to: "polls/answers#delete"
post :create_answer, to: "polls/answers#create"
get :load_answers
end
end end
end end

View File

@@ -0,0 +1,11 @@
class DropVotationTypes < ActiveRecord::Migration[5.0]
def up
drop_table :votation_set_answers
drop_table :poll_pair_answers
drop_table :votation_types
end
def down
fail ActiveRecord::IrreversibleMigration
end
end

View File

@@ -0,0 +1,9 @@
class RemoveOrderPositiveAndValueFromPollAnswers < ActiveRecord::Migration[5.0]
def change
remove_column :poll_answers, :value, :integer
remove_column :poll_answers, :positive, :boolean
remove_column :poll_answers, :order, :integer
remove_column :poll_question_answers, :hidden, :boolean, default: false
end
end

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20191030011956) do ActiveRecord::Schema.define(version: 20191030160347) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -1039,9 +1039,6 @@ ActiveRecord::Schema.define(version: 20191030011956) do
t.string "answer" t.string "answer"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.boolean "positive"
t.integer "order"
t.integer "value"
t.index ["author_id"], name: "index_poll_answers_on_author_id", using: :btree t.index ["author_id"], name: "index_poll_answers_on_author_id", using: :btree
t.index ["question_id", "answer"], name: "index_poll_answers_on_question_id_and_answer", using: :btree t.index ["question_id", "answer"], name: "index_poll_answers_on_question_id_and_answer", using: :btree
t.index ["question_id"], name: "index_poll_answers_on_question_id", using: :btree t.index ["question_id"], name: "index_poll_answers_on_question_id", using: :btree
@@ -1097,19 +1094,6 @@ ActiveRecord::Schema.define(version: 20191030011956) do
t.index ["user_id"], name: "index_poll_officers_on_user_id", using: :btree t.index ["user_id"], name: "index_poll_officers_on_user_id", using: :btree
end end
create_table "poll_pair_answers", force: :cascade do |t|
t.integer "question_id"
t.integer "author_id"
t.integer "answer_right_id"
t.integer "answer_left_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["answer_left_id"], name: "index_poll_pair_answers_on_answer_left_id", using: :btree
t.index ["answer_right_id"], name: "index_poll_pair_answers_on_answer_right_id", using: :btree
t.index ["author_id"], name: "index_poll_pair_answers_on_author_id", using: :btree
t.index ["question_id"], name: "index_poll_pair_answers_on_question_id", using: :btree
end
create_table "poll_partial_results", force: :cascade do |t| create_table "poll_partial_results", force: :cascade do |t|
t.integer "question_id" t.integer "question_id"
t.integer "author_id" t.integer "author_id"
@@ -1153,7 +1137,6 @@ ActiveRecord::Schema.define(version: 20191030011956) do
t.integer "question_id" t.integer "question_id"
t.integer "given_order", default: 1 t.integer "given_order", default: 1
t.boolean "most_voted", default: false t.boolean "most_voted", default: false
t.boolean "hidden", default: false
t.index ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree t.index ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree
end end
@@ -1670,29 +1653,6 @@ ActiveRecord::Schema.define(version: 20191030011956) do
t.index ["user_id"], name: "index_visits_on_user_id", using: :btree t.index ["user_id"], name: "index_visits_on_user_id", using: :btree
end end
create_table "votation_set_answers", force: :cascade do |t|
t.integer "author_id"
t.integer "votation_type_id"
t.string "answer"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["author_id"], name: "index_votation_set_answers_on_author_id", using: :btree
t.index ["votation_type_id"], name: "index_votation_set_answers_on_votation_type_id", using: :btree
end
create_table "votation_types", force: :cascade do |t|
t.integer "questionable_id"
t.string "questionable_type"
t.integer "enum_type"
t.boolean "open_answer"
t.boolean "prioritized"
t.integer "prioritization_type"
t.integer "max_votes"
t.integer "max_groups_answers"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "votes", force: :cascade do |t| create_table "votes", force: :cascade do |t|
t.string "votable_type" t.string "votable_type"
t.integer "votable_id" t.integer "votable_id"
@@ -1801,5 +1761,4 @@ ActiveRecord::Schema.define(version: 20191030011956) do
add_foreign_key "trackers", "users" add_foreign_key "trackers", "users"
add_foreign_key "users", "geozones" add_foreign_key "users", "geozones"
add_foreign_key "valuators", "users" add_foreign_key "valuators", "users"
add_foreign_key "votation_set_answers", "votation_types"
end end

View File

@@ -63,69 +63,6 @@ FactoryBot.define do
create(:poll_question_answer, question: question, title: "No") create(:poll_question_answer, question: question, title: "No")
end end
end end
factory :poll_question_unique do
after(:create) do |question|
create(:votation_type_unique, questionable: question)
question.reload
end
end
factory :poll_question_multiple do
after(:create) do |question|
create(:votation_type_multiple, questionable: question)
question.reload
end
end
factory :poll_question_prioritized do
after(:create) do |question|
create(:votation_type_prioritized, questionable: question)
question.reload
end
end
factory :poll_question_positive_open do
after(:create) do |question|
create(:votation_type_positive_open, questionable: question)
question.reload
end
end
factory :poll_question_positive_negative_open do
after(:create) do |question|
create(:votation_type_positive_negative_open, questionable: question)
question.reload
end
end
factory :poll_question_answer_couples_open do
after(:create) do |question|
create(:votation_type_answer_couples_open, questionable: question)
question.reload
end
end
factory :poll_question_answer_couples_closed do
after(:create) do |question|
create(:votation_type_answer_couples_closed, questionable: question)
question.reload
end
end
factory :poll_question_answer_set_open do
after(:create) do |question|
create(:votation_type_answer_set_open, questionable: question)
question.reload
end
end
factory :poll_question_answer_set_closed do
after(:create) do |question|
create(:votation_type_answer_set_closed, questionable: question)
question.reload
end
end
end end
factory :poll_question_answer, class: "Poll::Question::Answer" do factory :poll_question_answer, class: "Poll::Question::Answer" do
@@ -279,11 +216,4 @@ FactoryBot.define do
factory :active_poll do factory :active_poll do
end end
factory :poll_pair_answer, class: "Poll::PairAnswer" do
question { create :poll_question }
author { create :user }
answer_left { create(:poll_question_answer, question: question) }
answer_right { create(:poll_question_answer, question: question) }
end
end end

View File

@@ -1,76 +0,0 @@
FactoryBot.define do
factory :votation_type do
factory :votation_type_unique do
enum_type { "unique" }
open_answer { false }
prioritized { false }
end
factory :votation_type_multiple do
enum_type { "multiple" }
open_answer { false }
prioritized { false }
max_votes { 5 }
end
factory :votation_type_prioritized do
enum_type { "prioritized" }
open_answer { false }
prioritized { true }
max_votes { 5 }
prioritization_type { "borda" }
end
factory :votation_type_positive_open do
enum_type { "positive_open" }
open_answer { true }
prioritized { false }
max_votes { 5 }
end
factory :votation_type_positive_negative_open do
enum_type { "positive_negative_open" }
open_answer { true }
prioritized { false }
max_votes { 5 }
prioritization_type { "borda" }
end
factory :votation_type_answer_couples_open do
enum_type { "answer_couples_open" }
open_answer { true }
prioritized { false }
max_votes { 5 }
end
factory :votation_type_answer_couples_closed do
enum_type { "answer_couples_open" }
open_answer { false }
prioritized { false }
max_votes { 5 }
end
factory :votation_type_answer_set_open do
enum_type { "answer_set_open" }
open_answer { true }
prioritized { false }
max_votes { 3 }
max_groups_answers { 5 }
end
factory :votation_type_answer_set_closed do
enum_type { "answer_set_open" }
open_answer { false }
prioritized { false }
max_votes { 3 }
max_groups_answers { 5 }
end
trait :open do
open_answer { true }
end
trait :prioritized do
prioritized { true }
end
end
end

View File

@@ -232,14 +232,12 @@ describe "Admin polls" do
scenario "Question list", :js do scenario "Question list", :js do
poll = create(:poll) poll = create(:poll)
question = create(:poll_question, poll: poll) question = create(:poll_question, poll: poll)
votation_type_question = create(:poll_question_unique, poll: poll)
other_question = create(:poll_question) other_question = create(:poll_question)
visit admin_poll_path(poll) visit admin_poll_path(poll)
expect(page).to have_content "Questions (2)" expect(page).to have_content "Questions (1)"
expect(page).to have_content question.title expect(page).to have_content question.title
expect(page).to have_content votation_type_question.title
expect(page).not_to have_content other_question.title expect(page).not_to have_content other_question.title
expect(page).not_to have_content "There are no questions assigned to this poll" expect(page).not_to have_content "There are no questions assigned to this poll"
end end

View File

@@ -13,7 +13,6 @@ describe "Admin poll questions" do
question1 = create(:poll_question, poll: poll1) question1 = create(:poll_question, poll: poll1)
question2 = create(:poll_question, poll: poll2) question2 = create(:poll_question, poll: poll2)
question3 = create(:poll_question, poll: poll3, proposal: proposal) question3 = create(:poll_question, poll: poll3, proposal: proposal)
question4 = create(:poll_question_unique, poll: poll1)
visit admin_poll_path(poll1) visit admin_poll_path(poll1)
expect(page).to have_content(poll1.name) expect(page).to have_content(poll1.name)
@@ -25,13 +24,6 @@ describe "Admin poll questions" do
expect(page).to have_content("Delete") expect(page).to have_content("Delete")
end end
within("#poll_question_#{question4.id}") do
expect(page).to have_content(question4.title)
expect(page).to have_content("Edit answers")
expect(page).to have_content("Edit")
expect(page).to have_content("Delete")
end
visit admin_poll_path(poll2) visit admin_poll_path(poll2)
expect(page).to have_content(poll2.name) expect(page).to have_content(poll2.name)
@@ -54,35 +46,16 @@ describe "Admin poll questions" do
end end
end end
context "Show" do scenario "Show" do
scenario "Without Votation type" do geozone = create(:geozone)
geozone = create(:geozone) poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id])
poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id]) question = create(:poll_question, poll: poll)
question = create(:poll_question, poll: poll)
visit admin_poll_path(poll) visit admin_poll_path(poll)
click_link question.title click_link question.title
expect(page).to have_content(question.title) expect(page).to have_content(question.title)
expect(page).to have_content(question.author.name) expect(page).to have_content(question.author.name)
expect(page).not_to have_content("Votation type")
end
scenario "With Votation type" do
geozone = create(:geozone)
poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id])
question = create(:poll_question_multiple, poll: poll)
visit admin_poll_path(poll)
click_link "#{question.title}"
expect(page).to have_content(question.title)
expect(page).to have_content(question.author.name)
expect(page).to have_content("Votation type")
expect(page).to have_content("Multiple")
expect(page).to have_content("Maximum number of votes")
expect(page).to have_content("5")
end
end end
scenario "Create" do scenario "Create" do
@@ -144,179 +117,6 @@ describe "Admin poll questions" do
expect(page).to have_content(proposal.title) expect(page).to have_content(proposal.title)
end end
context "create with votation type" do
before do
poll = create(:poll, name: "Movies")
visit admin_poll_path(poll)
click_link "Create question"
end
scenario "unique" do
title = "unique question"
fill_in "Question", with: title
select "Unique answer, closed", from: "votation_type_enum_type"
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Unique answer, closed")
end
scenario "multiple" do
title = "multiple question"
fill_in "Question", with: title
select "Multiple answers, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Multiple answers, closed")
end
scenario "prioritized" do
title = "prioritized question"
fill_in "Question", with: title
select "Multiple prioritized answer, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Multiple prioritized answer, closed")
end
scenario "positive_open" do
title = "positive open question"
fill_in "Question", with: title
select "Votable positive, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Votable positive, open")
end
scenario "positive_negative_open" do
title = "positive negative open question"
fill_in "Question", with: title
select "Votable positive and negative, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Votable positive and negative, open")
end
scenario "answer_couples_open" do
title = "answer couples open question"
fill_in "Question", with: title
select "Couples of answers, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Couples of answers, open")
end
scenario "answer_couples_closed" do
title = "answer couples closed question"
fill_in "Question", with: title
select "Couples of answers, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Couples of answers, closed")
end
scenario "answer_set_open" do
title = "answer set open question"
fill_in "Question", with: title
select "Set of answers, open", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of answers in the set", with: 3
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Set of answers, open")
end
scenario "answer_set_closed" do
title = "answer set closed question"
fill_in "Question", with: title
select "Set of answers, closed", from: "votation_type_enum_type"
expect(page).to have_content("Maximum number of votes")
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of votes", with: 6
click_button "Save"
expect(page).to have_content("1 error prevented this Poll/Question from being saved.")
fill_in "Maximum number of answers in the set", with: 3
click_button "Save"
expect(page).to have_content(title)
expect(page).to have_content("Set of answers, closed")
end
end
scenario "Update" do scenario "Update" do
poll = create(:poll) poll = create(:poll)
question1 = create(:poll_question, poll: poll) question1 = create(:poll_question, poll: poll)

View File

@@ -1,376 +0,0 @@
require "rails_helper"
describe "Poll Votation Type" do
context "Unique" do
let(:user) { create(:user, :verified) }
let(:poll_current) { create(:poll, :current) }
let(:unique) { create(:poll_question_unique, poll: poll_current) }
let!(:answer1) { create(:poll_question_answer, question: unique, title: "answer_1") }
let!(:answer2) { create(:poll_question_answer, question: unique, title: "answer_2") }
before do
login_as(user)
end
scenario "response question without votation type" do
question = create(:poll_question, :yes_no, poll: poll_current)
visit poll_path(poll_current)
expect(page).to have_content(question.title)
expect(page).to have_content(answer1.title)
end
scenario "response question with votation type" do
visit poll_path(poll_current)
expect(page).to have_content(unique.title)
expect(page).to have_content(answer1.title)
end
scenario "response question vote", :js do
visit poll_path(poll_current)
within("#poll_question_#{unique.id}_answers") do
click_link answer1.title
expect(page).to have_link answer2.title
expect(page).not_to have_link answer1.title
end
end
scenario "response question change vote", :js do
visit poll_path(poll_current)
within("#poll_question_#{unique.id}_answers") do
click_link answer1.title
expect(page).to have_link answer2.title
expect(page).not_to have_link answer1.title
click_link answer2.title
expect(page).to have_link answer1.title
expect(page).not_to have_link answer2.title
end
end
end
context "Multiple" do
let(:user) { create(:user, :verified) }
let(:poll_current) { create(:poll, :current) }
let(:question) { create(:poll_question_multiple, poll: poll_current) }
let!(:answer1) { create(:poll_question_answer, question: question, title: "answer_1") }
before do
create(:poll_question_answer, question: question, title: "answer_2")
create(:poll_question_answer, question: question, title: "answer_3")
create(:poll_question_answer, question: question, title: "answer_4")
create(:poll_question_answer, question: question, title: "answer_5")
login_as(user)
end
scenario "response question" do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
expect(page).to have_content(answer.title)
end
end
end
scenario "response question vote", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
expect(page).to have_link answer.title, class: "answered"
end
end
end
scenario "response question no more vote than allowed", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
expect(page).to have_link text: answer.title, class: "answered"
end
end
answer6 = create(:poll_question_answer, question: question, title: "answer_6")
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link answer6.title
expect(page).not_to have_link text: answer6.title, class: "answered"
end
end
scenario "response question remove vote and vote again", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
end
end
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link answer1.title
expect(page).not_to have_link text: answer1.title, class: "answered"
end
answer6 = create(:poll_question_answer, question: question, title: "answer_6")
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
expect(page).to have_link answer6.title
click_link answer6.title
expect(page).to have_link answer6.title, class: "answered"
end
end
end
context "Prioritized" do
let(:user) { create(:user, :verified) }
let(:poll_current) { create(:poll, :current) }
let(:question) { create(:poll_question_prioritized, poll: poll_current) }
before do
create(:poll_question_answer, question: question, title: "answer_1")
create(:poll_question_answer, question: question, title: "answer_2")
create(:poll_question_answer, question: question, title: "answer_3")
create(:poll_question_answer, question: question, title: "answer_4")
create(:poll_question_answer, question: question, title: "answer_5")
login_as(user)
end
scenario "response question" do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
expect(page).to have_content(answer.title)
end
end
end
scenario "response question vote", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
end
end
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
expect(page).to have_link answer.title
end
end
end
scenario "response question no more vote than allowed", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
expect(page).to have_link text: answer.title, class: "answered"
end
end
answer6 = create(:poll_question_answer, question: question, title: "answer_6")
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link answer6.title
expect(page).not_to have_link answer6.title, class: "answered"
end
end
end
context "Positive open" do
let(:user) { create(:user, :verified) }
let(:poll_current) { create(:poll, :current) }
let(:question) { create(:poll_question_positive_open, poll: poll_current) }
let!(:answer1) { create(:poll_question_answer, question: question, title: "answer_1") }
before do
create(:poll_question_answer, question: question, title: "answer_2")
create(:poll_question_answer, question: question, title: "answer_3")
create(:poll_question_answer, question: question, title: "answer_4")
create(:poll_question_answer, question: question, title: "answer_5")
login_as(user)
end
scenario "response question" do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
expect(page).to have_content(answer.title)
end
end
end
scenario "response question vote", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
expect(page).to have_link answer.title, class: "answered"
end
end
end
scenario "response question no more vote than allowed", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
expect(page).to have_link text: answer.title, class: "answered"
end
end
answer6 = create(:poll_question_answer, question: question, title: "answer_6")
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link answer6.title
expect(page).not_to have_link answer6.title, class: "answered"
end
end
scenario "response question remove vote and vote again", :js do
visit poll_path(poll_current)
question.question_answers.each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.title
expect(page).to have_link text: answer.title, class: "answered"
end
end
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link answer1.title
expect(page).not_to have_link text: answer1.title, class: "answered"
end
answer6 = create(:poll_question_answer, question: question, title: "answer_6")
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link answer6.title
expect(page).to have_link answer6.title, class: "answered"
end
end
scenario "add answer", :js do
visit poll_path(poll_current)
fill_in "answer", with: "Added answer"
click_button "Add answer"
expect(page).to have_link "Added answer"
visit poll_path(poll_current)
within("#poll_question_#{question.id}_answers") do
click_link "Added answer"
expect(page).to have_link "Added answer", class: "answered"
end
end
scenario "existing given order is bigger than the number of answers", :js do
answer1.update!(given_order: question.question_answers.count + 1)
visit poll_path(poll_current)
fill_in "answer", with: "Added answer"
click_button "Add answer"
expect(page).to have_link "Added answer"
end
end
context "Answers set" do
let(:user) { create(:user, :verified) }
let(:poll_current) { create(:poll, :current) }
let(:question) { create(:poll_question_answer_set_open, poll: poll_current) }
before do
create(:poll_question_answer, question: question, title: "answer_1")
create(:poll_question_answer, question: question, title: "answer_2")
create(:poll_question_answer, question: question, title: "answer_3")
create(:poll_question_answer, question: question, title: "answer_4")
create(:poll_question_answer, question: question, title: "answer_5")
login_as(user)
end
scenario "response question" do
visit poll_path(poll_current)
expect(page.find("#poll_question_#{question.id}_answers")).to have_css("a", count: question.max_groups_answers)
end
scenario "response question vote", :js do
visit poll_path(poll_current)
question.votation_type.votation_set_answers.by_author(user).each do |answer|
within("#poll_question_#{question.id}_answers") do
click_link answer.answer
end
end
within("#poll_question_#{question.id}_answers") do
expect(page).to have_css(".answered", count: question.max_votes)
end
end
scenario "add answer", :js do
visit poll_path(poll_current)
fill_in "answer", with: "added_answer"
click_button "Add answer"
within("#poll_question_#{question.id}_answers") do
expect(page).to have_content("Answer added succesfully")
end
end
end
end

View File

@@ -91,7 +91,6 @@ describe Abilities::Administrator do
it { should be_able_to(:read, Poll::Question) } it { should be_able_to(:read, Poll::Question) }
it { should be_able_to(:create, Poll::Question) } it { should be_able_to(:create, Poll::Question) }
it { should be_able_to(:update, Poll::Question) } it { should be_able_to(:update, Poll::Question) }
it { should be_able_to(:get_options_traductions, Poll::Question) }
it { is_expected.to be_able_to :manage, Dashboard::AdministratorTask } it { is_expected.to be_able_to :manage, Dashboard::AdministratorTask }
it { is_expected.to be_able_to :manage, dashboard_administrator_task } it { is_expected.to be_able_to :manage, dashboard_administrator_task }

View File

@@ -215,18 +215,6 @@ describe Abilities::Common do
it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones) } it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones) }
it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone) } it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone) }
it { should be_able_to(:prioritized_answers, poll_question_from_own_geozone) }
it { should be_able_to(:prioritized_answers, poll_question_from_all_geozones) }
it { should_not be_able_to(:prioritized_answers, poll_question_from_other_geozone) }
it { should_not be_able_to(:prioritized_answers, expired_poll_question_from_own_geozone) }
it { should_not be_able_to(:prioritized_answers, expired_poll_question_from_all_geozones) }
it { should_not be_able_to(:prioritized_answers, expired_poll_question_from_other_geozone) }
context "Poll::Question" do
it { should be_able_to(:load_answers, Poll::Question) }
end
context "without geozone" do context "without geozone" do
before { user.geozone = nil } before { user.geozone = nil }

View File

@@ -1,118 +0,0 @@
require "rails_helper"
describe Poll::PairAnswer do
describe "validations" do
let(:pair_answer) { build(:poll_pair_answer) }
it "is valid" do
expect(pair_answer).to be_valid
end
it "is not valid wihout a question" do
pair_answer.question = nil
expect(pair_answer).not_to be_valid
end
it "is not valid without an author" do
pair_answer.author = nil
expect(pair_answer).not_to be_valid
end
it "is valid if answer_left is included in the Poll::Question's question_answers list" do
question = create(:poll_question)
answer1 = create(:poll_question_answer, title: "One", question: question)
answer2 = create(:poll_question_answer, title: "Two", question: question)
answer3 = create(:poll_question_answer, title: "Three")
expect(build(:poll_pair_answer, question: question, answer_left: answer1)).to be_valid
expect(build(:poll_pair_answer, question: question, answer_left: answer2)).to be_valid
expect(build(:poll_pair_answer, question: question, answer_left: answer3)).not_to be_valid
end
it "is valid if answer_right is included in the Poll::Question's question_answers list" do
question = create(:poll_question)
answer1 = create(:poll_question_answer, title: "One", question: question)
answer2 = create(:poll_question_answer, title: "Two", question: question)
answer3 = create(:poll_question_answer, title: "Three")
expect(build(:poll_pair_answer, question: question, answer_right: answer1)).to be_valid
expect(build(:poll_pair_answer, question: question, answer_right: answer2)).to be_valid
expect(build(:poll_pair_answer, question: question, answer_right: answer3)).not_to be_valid
end
end
context "scopes" do
let(:pair_answer_1) { create(:poll_pair_answer) }
let(:pair_answer_2) { create(:poll_pair_answer) }
describe "#by_author" do
it "returns pair_answers associated to an user" do
author = pair_answer_1.author
expect(Poll::PairAnswer.by_author(author)).to eq [pair_answer_1]
end
end
describe "#by_question" do
it "returns pair_answers associated to a question" do
question = pair_answer_1.question
expect(Poll::PairAnswer.by_question(question)).to eq [pair_answer_1]
end
end
end
describe "#generate_pair" do
let(:user) { create(:user) }
let(:question) { create(:poll_question) }
context "without question_answers" do
it "assigns nil value to pair_answers" do
pair_answer = Poll::PairAnswer.generate_pair(question, user)
expect(pair_answer).to be_a Poll::PairAnswer
expect(pair_answer.question).to eq(question)
expect(pair_answer.author).to eq(user)
expect(pair_answer.answer_left).to be_nil
expect(pair_answer.answer_right).to be_nil
end
end
context "With question answers" do
let!(:answer1) { create(:poll_question_answer, question: question) }
it "assigns only right question if only has one question_answer" do
pair_answer = Poll::PairAnswer.generate_pair(question, user)
expect(pair_answer).to be_a Poll::PairAnswer
expect(pair_answer.question).to eq(question)
expect(pair_answer.author).to eq(user)
expect(pair_answer.answer_left).to eq(answer1)
expect(pair_answer.answer_right).to be_nil
end
it "assigns random values if question has some question_answer" do
create(:poll_question_answer, question: question)
pair_answer = Poll::PairAnswer.generate_pair(question, user)
expect(pair_answer).to be_a Poll::PairAnswer
expect(pair_answer.question).to eq(question)
expect(pair_answer.author).to eq(user)
expect(pair_answer.answer_left).to be_a Poll::Question::Answer
expect(pair_answer.answer_right).to be_a Poll::Question::Answer
expect(pair_answer.answer_left).not_to eq(pair_answer.answer_right)
end
end
end
describe "#answers" do
let(:pair_answer) { create(:poll_pair_answer) }
it "returns an array of answers" do
expect(pair_answer.answers).to eq [pair_answer.answer_left, pair_answer.answer_right]
end
end
end

View File

@@ -45,32 +45,4 @@ RSpec.describe Poll::Question, type: :model do
end end
end end
end end
describe "#enum_type" do
it "returns nil if not has votation_type association" do
expect(poll_question.votation_type).to be_nil
expect(poll_question.enum_type).to be_nil
end
it "returns enum_type from votation_type association" do
question = create(:poll_question_answer_couples_open)
expect(question.votation_type).not_to be_nil
expect(question.enum_type).to eq("answer_couples_open")
end
end
describe "#max_votes" do
it "returns nil if not has votation_type association" do
expect(poll_question.votation_type).to be_nil
expect(poll_question.max_votes).to be_nil
end
it "returns max_votes from votation_type association" do
question = create(:poll_question_answer_couples_open)
expect(question.votation_type).not_to be_nil
expect(question.max_votes).to eq(5)
end
end
end end