Merge branch 'master' into 1786-poll_results

This commit is contained in:
María Checa
2017-10-18 17:33:16 +02:00
69 changed files with 765 additions and 432 deletions

View File

@@ -1,12 +1,12 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2017-07-07 21:23:30 +0200 using RuboCop version 0.49.1.
# on 2017-10-17 22:05:23 +0200 using RuboCop version 0.49.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 45
# Offense count: 40
# Cop supports --auto-correct.
# Configuration parameters: EnforcedHashRocketStyle, SupportedHashRocketStyles, EnforcedColonStyle, SupportedColonStyles, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles.
# SupportedHashRocketStyles: key, separator, table
@@ -14,11 +14,10 @@
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/AlignHash:
Exclude:
- 'app/controllers/officing/results_controller.rb'
- 'spec/controllers/legislation/annotations_controller_spec.rb'
- 'spec/features/admin/banners_spec.rb'
# Offense count: 50
# Offense count: 52
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
# SupportedStyles: with_first_parameter, with_fixed_indentation
@@ -33,7 +32,7 @@ Layout/ClosingParenthesisIndentation:
- 'spec/models/legislation/annotation_spec.rb'
- 'spec/rails_helper.rb'
# Offense count: 51
# Offense count: 37
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: leading, trailing
@@ -68,11 +67,10 @@ Layout/EmptyLines:
Exclude:
- 'app/controllers/admin/budget_investment_milestones_controller.rb'
# Offense count: 2
# Offense count: 1
# Cop supports --auto-correct.
Layout/EmptyLinesAroundMethodBody:
Exclude:
- 'app/models/abilities/administrator.rb'
- 'lib/graph_ql/api_types_creator.rb'
# Offense count: 2
@@ -126,13 +124,13 @@ Layout/IndentationConsistency:
- 'spec/models/legislation/draft_version_spec.rb'
- 'spec/models/proposal_spec.rb'
# Offense count: 23
# Offense count: 48
# Cop supports --auto-correct.
# Configuration parameters: Width, IgnoredPatterns.
Layout/IndentationWidth:
Enabled: false
# Offense count: 7
# Offense count: 6
# Cop supports --auto-correct.
Layout/LeadingCommentSpace:
Exclude:
@@ -140,7 +138,6 @@ Layout/LeadingCommentSpace:
- 'app/controllers/budgets/ballot/lines_controller.rb'
- 'spec/features/budgets/ballots_spec.rb'
- 'spec/features/comments/poll_questions_spec.rb'
- 'spec/features/officing/voters_spec.rb'
- 'spec/support/common_actions.rb'
# Offense count: 3
@@ -181,7 +178,7 @@ Layout/MultilineMethodCallBraceLayout:
- 'spec/models/legislation/annotation_spec.rb'
- 'spec/rails_helper.rb'
# Offense count: 71
# Offense count: 59
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
# SupportedStyles: aligned, indented, indented_relative_to_receiver
@@ -201,7 +198,7 @@ Layout/MultilineMethodCallIndentation:
- 'spec/models/proposal_spec.rb'
- 'spec/models/user_spec.rb'
# Offense count: 8
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
# SupportedStyles: aligned, indented
@@ -264,22 +261,7 @@ Lint/LiteralInCondition:
Exclude:
- 'app/models/budget/investment.rb'
# Offense count: 51
Lint/ParenthesesAsGroupedExpression:
Exclude:
- 'spec/factories.rb'
- 'spec/features/admin/organizations_spec.rb'
- 'spec/features/budgets/investments_spec.rb'
- 'spec/features/campaigns_spec.rb'
- 'spec/features/debates_spec.rb'
- 'spec/features/management/managed_users_spec.rb'
- 'spec/features/management/proposals_spec.rb'
- 'spec/features/management/spending_proposals_spec.rb'
- 'spec/features/management/users_spec.rb'
- 'spec/features/proposals_spec.rb'
- 'spec/models/debate_spec.rb'
# Offense count: 13
# Offense count: 3
# Cop supports --auto-correct.
Lint/StringConversionInInterpolation:
Exclude:
@@ -308,7 +290,7 @@ Lint/UnusedMethodArgument:
- 'app/mailers/mailer.rb'
- 'app/models/abilities/everyone.rb'
# Offense count: 278
# Offense count: 325
Lint/UselessAssignment:
Enabled: false
@@ -317,35 +299,46 @@ Lint/Void:
Exclude:
- 'app/controllers/polls_controller.rb'
# Offense count: 74
# Offense count: 86
Metrics/AbcSize:
Max: 54
Max: 64
# Offense count: 454
# Offense count: 487
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 1071
# Offense count: 8
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 256
Max: 1227
# Offense count: 10
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 262
# Offense count: 13
Metrics/CyclomaticComplexity:
Max: 10
# Offense count: 53
# Offense count: 25
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
# URISchemes: http, https
Metrics/LineLength:
Max: 248
# Offense count: 67
# Configuration parameters: CountComments.
Metrics/MethodLength:
Max: 49
Max: 56
# Offense count: 1
# Configuration parameters: CountComments.
Metrics/ModuleLength:
Max: 214
Max: 242
# Offense count: 7
# Offense count: 3
# Configuration parameters: CountKeywordArgs.
Metrics/ParameterLists:
Max: 7
# Offense count: 8
Metrics/PerceivedComplexity:
Max: 11
@@ -399,20 +392,20 @@ Rails/HttpPositionalArguments:
- 'spec/controllers/pages_controller_spec.rb'
- 'spec/controllers/users/registrations_controller_spec.rb'
# Offense count: 20
# Offense count: 18
Rails/OutputSafety:
Exclude:
- 'app/controllers/admin/legislation/draft_versions_controller.rb'
- 'app/controllers/admin/legislation/processes_controller.rb'
- 'app/controllers/admin/legislation/questions_controller.rb'
- 'app/controllers/budgets/investments_controller.rb'
- 'app/controllers/direct_uploads_controller.rb'
- 'app/controllers/spending_proposals_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/helpers/text_with_links_helper.rb'
- 'app/helpers/users_helper.rb'
- 'app/helpers/valuation_helper.rb'
# Offense count: 70
# Offense count: 71
# Configuration parameters: Blacklist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
@@ -428,7 +421,7 @@ Style/AccessorMethodName:
- 'app/controllers/proposals_controller.rb'
- 'lib/merged_comment_tree.rb'
# Offense count: 1
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: braces, no_braces, context_dependent
@@ -438,7 +431,7 @@ Style/BracesAroundHashParameters:
- 'spec/features/budgets/investments_spec.rb'
- 'spec/features/proposals_spec.rb'
# Offense count: 119
# Offense count: 123
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: nested, compact
Style/ClassAndModuleChildren:
@@ -451,14 +444,13 @@ Style/ClassVars:
- 'app/models/organization.rb'
- 'app/models/user.rb'
# Offense count: 12
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly, IncludeTernaryExpressions.
# SupportedStyles: assign_to_condition, assign_inside_condition
Style/ConditionalAssignment:
Exclude:
- 'app/controllers/admin/poll/booth_assignments_controller.rb'
- 'app/controllers/admin/poll/officer_assignments_controller.rb'
- 'app/controllers/admin/poll/questions_controller.rb'
- 'app/controllers/comments_controller.rb'
- 'app/controllers/management/spending_proposals_controller.rb'
@@ -484,7 +476,7 @@ Style/FileName:
Style/GuardClause:
Enabled: false
# Offense count: 12
# Offense count: 11
# Cop supports --auto-correct.
# Configuration parameters: MaxLineLength.
Style/IfUnlessModifier:
@@ -495,19 +487,19 @@ Style/IfUnlessModifier:
- 'app/controllers/legislation/annotations_controller.rb'
- 'app/controllers/valuation/budget_investments_controller.rb'
- 'app/controllers/verification/letter_controller.rb'
- 'app/controllers/welcome_controller.rb'
- 'app/helpers/embed_videos_helper.rb'
- 'app/mailers/mailer.rb'
- 'app/models/proposal.rb'
- 'app/models/spending_proposal.rb'
# Offense count: 4
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: line_count_dependent, lambda, literal
Style/Lambda:
Exclude:
- 'app/models/comment.rb'
- 'app/models/concerns/followable.rb'
- 'app/models/direct_message.rb'
- 'app/models/vote.rb'
- 'lib/graph_ql/api_types_creator.rb'
@@ -523,7 +515,7 @@ Style/MultilineIfThen:
Exclude:
- 'app/controllers/management/users_controller.rb'
# Offense count: 15
# Offense count: 13
# Cop supports --auto-correct.
Style/MutableConstant:
Exclude:
@@ -546,7 +538,7 @@ Style/MutableConstant:
Style/NumericLiterals:
MinDigits: 9
# Offense count: 19
# Offense count: 20
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
# SupportedStyles: predicate, comparison
@@ -574,7 +566,7 @@ Style/ParallelAssignment:
- 'lib/active_model/dates.rb'
- 'spec/support/common_actions.rb'
# Offense count: 11
# Offense count: 10
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
# NamePrefix: is_, has_, have_
# NamePrefixBlacklist: is_, has_, have_
@@ -588,7 +580,6 @@ Style/PredicateName:
- 'app/helpers/debates_helper.rb'
- 'app/models/budget/ballot.rb'
- 'app/models/user.rb'
- 'lib/census_api.rb'
# Offense count: 4
# Cop supports --auto-correct.
@@ -608,13 +599,14 @@ Style/RedundantBegin:
- 'app/controllers/graphql_controller.rb'
- 'app/models/legislation/annotation.rb'
# Offense count: 3
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Exclude:
- 'app/helpers/embed_videos_helper.rb'
- 'app/models/poll/question/answer/video.rb'
- 'spec/customization_engine_spec.rb'
# Offense count: 6
@@ -633,22 +625,16 @@ Style/SafeNavigation:
Exclude:
- 'app/models/signature.rb'
# Offense count: 9
# Configuration parameters: SupportedStyles.
# SupportedStyles: snake_case, camelCase
Style/VariableName:
EnforcedStyle: snake_case
# Offense count: 107
# Offense count: 93
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: snake_case, normalcase, non_integer
Style/VariableNumber:
Enabled: false
# Offense count: 31
# Offense count: 34
# Cop supports --auto-correct.
# Configuration parameters: SupportedStyles, WordRegex.
# SupportedStyles: percent, brackets
Style/WordArray:
EnforcedStyle: percent
MinSize: 9
MinSize: 8

View File

@@ -54,7 +54,7 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController
end
def poll_params
params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, :summary, :description,
params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, :summary, :description,
geozone_ids: [],
image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy])
end

View File

@@ -5,7 +5,7 @@ class Admin::Poll::Questions::Answers::ImagesController < Admin::Poll::BaseContr
end
def new
@answer = ::Poll::Question::Answer.find(params[:answer_id])
@answer = ::Poll::Question::Answer.find(params[:answer_id])
end
def create

View File

@@ -33,11 +33,11 @@ class Admin::Poll::Questions::Answers::VideosController < Admin::Poll::BaseContr
end
def destroy
if @video.destroy
notice = t("flash.actions.destroy.poll_question_answer_video")
else
notice = t("flash.actions.destroy.error")
end
notice = if @video.destroy
t("flash.actions.destroy.poll_question_answer_video")
else
t("flash.actions.destroy.error")
end
redirect_to :back, notice: notice
end

View File

@@ -15,7 +15,6 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
def new
@polls = Poll.all
@question.valid_answers = I18n.t('poll_questions.default_valid_answers')
proposal = Proposal.find(params[:proposal_id]) if params[:proposal_id].present?
@question.copy_attributes_from_proposal(proposal)
end
@@ -56,7 +55,7 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController
private
def question_params
params.require(:poll_question).permit(:poll_id, :title, :question, :proposal_id, :valid_answers, :video_url)
params.require(:poll_question).permit(:poll_id, :title, :question, :proposal_id, :video_url)
end
def search_params

View File

@@ -49,7 +49,7 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController
end
def shift_params
shift_params = params.require(:shift).permit(:booth_id, :officer_id, :task, date:[:vote_collection_date, :recount_scrutiny_date])
shift_params = params.require(:shift).permit(:booth_id, :officer_id, :task, date: [:vote_collection_date, :recount_scrutiny_date])
shift_params.merge(date: shift_params[:date]["#{shift_params[:task]}_date".to_sym])
end
end

View File

@@ -18,8 +18,7 @@ class DirectUploadsController < ApplicationController
render json: { cached_attachment: @direct_upload.relation.cached_attachment,
filename: @direct_upload.relation.attachment.original_filename,
destroy_link: render_destroy_upload_link(@direct_upload).html_safe,
attachment_url: @direct_upload.relation.attachment.url
}
attachment_url: @direct_upload.relation.attachment.url}
else
@direct_upload.destroy_attachment
render json: { errors: @direct_upload.errors[:attachment].join(", ") },
@@ -28,7 +27,7 @@ class DirectUploadsController < ApplicationController
end
def destroy
@direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user) )
@direct_upload = DirectUpload.new(direct_upload_params.merge(user: current_user))
@direct_upload.relation.set_attachment_from_cached_attachment
if @direct_upload.destroy_attachment

View File

@@ -5,7 +5,7 @@ class Officing::ResultsController < Officing::BaseController
before_action :load_partial_results, only: :new
before_action :load_officer_assignment, only: :create
before_action :check_booth_and_date, only: :create
before_action :check_officer_assignment, only: :create
before_action :build_results, only: :create
def new
@@ -32,13 +32,9 @@ class Officing::ResultsController < Officing::BaseController
private
def check_booth_and_date
def check_officer_assignment
if @officer_assignment.blank?
go_back_to_new(t("officing.results.flash.error_wrong_booth"))
elsif results_params[:date].blank? ||
Date.parse(results_params[:date]) < @poll.starts_at.to_date ||
Date.parse(results_params[:date]) > @poll.ends_at.to_date
go_back_to_new(t("officing.results.flash.error_wrong_date"))
end
end
@@ -51,11 +47,11 @@ class Officing::ResultsController < Officing::BaseController
results.each_pair do |answer_index, count|
next if count.blank?
answer = question.valid_answers[answer_index.to_i]
answer = question.question_answers.where(given_order: answer_index.to_i + 1).first.title
go_back_to_new if question.blank?
partial_result = ::Poll::PartialResult.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
date: results_params[:date],
date: Date.current,
question_id: question_id,
answer: answer)
partial_result.officer_assignment_id = @officer_assignment.id
@@ -71,7 +67,7 @@ class Officing::ResultsController < Officing::BaseController
def build_recounts
recount = ::Poll::Recount.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id,
date: results_params[:date])
date: Date.current)
recount.officer_assignment_id = @officer_assignment.id
recount.author = current_user
recount.origin = 'booth'
@@ -84,7 +80,7 @@ class Officing::ResultsController < Officing::BaseController
end
def go_back_to_new(alert = nil)
params[:d] = results_params[:date]
params[:d] = Date.current
params[:oa] = results_params[:officer_assignment_id]
flash.now[:alert] = (alert || t("officing.results.flash.error_create"))
load_officer_assignments
@@ -108,7 +104,7 @@ class Officing::ResultsController < Officing::BaseController
final.
where(id: current_user.poll_officer.officer_assignment_ids).
where("poll_booth_assignments.poll_id = ?", @poll.id).
order(date: :asc)
where(date: Date.current)
end
def load_partial_results
@@ -119,7 +115,7 @@ class Officing::ResultsController < Officing::BaseController
end
def results_params
params.permit(:officer_assignment_id, :date, :questions, :whites, :nulls, :total)
params.permit(:officer_assignment_id, :questions, :whites, :nulls, :total)
end
def index_params

View File

@@ -25,6 +25,8 @@ class PollsController < ApplicationController
@commentable = @poll
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
@stats = Poll::Stats.new(@poll).generate
end
def results

View File

@@ -24,8 +24,8 @@ module DocumentablesHelper
def documentable_humanized_accepted_content_types(documentable_class)
documentable_class.accepted_content_types
.collect{ |content_type| content_type.split("/").last }
.join(", ")
.collect{ |content_type| content_type.split("/").last }
.join(", ")
end
def documentables_note(documentable)

View File

@@ -33,7 +33,7 @@ module DocumentsHelper
def render_attachment(builder, document)
klass = document.errors[:attachment].any? ? "error" : ""
klass = document.persisted? || document.cached_attachment.present? ? " hide" : ""
klass = document.persisted? || document.cached_attachment.present? ? " hide" : ""
html = builder.label :attachment,
t("documents.form.attachment_label"),
class: "button hollow #{klass}"

View File

@@ -9,10 +9,10 @@ module ImageablesHelper
end
def imageable_max_file_size
bytesToMeg(Image::MAX_IMAGE_SIZE)
bytes_to_megabytes(Image::MAX_IMAGE_SIZE)
end
def bytesToMeg(bytes)
def bytes_to_megabytes(bytes)
bytes / Numeric::MEGABYTE
end
@@ -22,19 +22,19 @@ module ImageablesHelper
def imageable_accepted_content_types_extensions
Image::ACCEPTED_CONTENT_TYPE
.collect{ |content_type| ".#{content_type.split("/").last}" }
.join(",")
.collect{ |content_type| ".#{content_type.split('/').last}" }
.join(",")
end
def imageable_humanized_accepted_content_types
Image::ACCEPTED_CONTENT_TYPE
.collect{ |content_type| content_type.split("/").last }
.join(", ")
.collect{ |content_type| content_type.split("/").last }
.join(", ")
end
def imageables_note(imageable)
def imageables_note(_imageable)
t "images.form.note", accepted_content_types: imageable_humanized_accepted_content_types,
max_file_size: imageable_max_file_size
end
end
end

View File

@@ -22,7 +22,7 @@ module ImagesHelper
image.errors[:attachment].join(', ') if image.errors.key?(:attachment)
end
def image_bytesToMeg(bytes)
def image_bytes_to_megabytes(bytes)
bytes / Numeric::MEGABYTE
end

View File

@@ -44,7 +44,7 @@ module PollsHelper
def poll_voter_token(poll, user)
Poll::Voter.where(poll: poll, user: user, origin: "web").first&.token || ''
end
def voted_before_sign_in(question)
question.answers.where(author: current_user).any? { |vote| current_user.current_sign_in_at >= vote.updated_at }
end

View File

@@ -1,11 +1,11 @@
module WelcomeHelper
def active_class(index)
"is-active is-in" if index == 0
"is-active is-in" if index.zero?
end
def slide_display(index)
"display: none;" if index > 0
"display: none;" if index.positive?
end
def recommended_path(recommended)
@@ -46,12 +46,12 @@ module WelcomeHelper
end
def calculate_offset(debates, proposals, apply_offset)
if (debates.any? && proposals.any?)
if apply_offset
offset = "medium-offset-2 large-offset-2"
else
offset = "end"
end
if debates.any? && proposals.any?
offset = if apply_offset
"medium-offset-2 large-offset-2"
else
"end"
end
end
end

View File

@@ -23,6 +23,7 @@ module Abilities
can [:read], Legislation::Question
can [:create], Legislation::Answer
can [:search, :comments, :read, :create, :new_comment], Legislation::Annotation
can :read_stats, Poll
end
end
end

View File

@@ -5,7 +5,7 @@ module Followable
has_many :follows, as: :followable, dependent: :destroy
has_many :followers, through: :follows, source: :user
scope :followed_by_user, -> (user){
scope :followed_by_user, ->(user){
joins(:follows).where("follows.user_id = ?", user.id)
}
end

View File

@@ -48,8 +48,8 @@ class Debate < ActiveRecord::Base
attr_accessor :link_required
def self.recommendations(user)
tagged_with(user.interests, any: true).
where("author_id != ?", user.id)
tagged_with(user.interests, any: true)
.where("author_id != ?", user.id)
end
def searchable_values

View File

@@ -7,7 +7,7 @@ class DirectUpload
:relation, :resource_relation,
:attachment, :cached_attachment, :user
validates_presence_of :attachment, :resource_type, :resource_relation, :user
validates :attachment, :resource_type, :resource_relation, :user, presence: true
validate :parent_resource_attachment_validations,
if: -> { attachment.present? && resource_type.present? && resource_relation.present? && user.present? }
@@ -19,15 +19,15 @@ class DirectUpload
if @resource_type.present? && @resource_relation.present? && (@attachment.present? || @cached_attachment.present?)
@resource = @resource_type.constantize.find_or_initialize_by(id: @resource_id)
#Refactor
if @resource.respond_to?(:images) &&
((@attachment.present? && !@attachment.content_type.match(/pdf/)) || @cached_attachment.present?)
@relation = @resource.images.send("build", relation_attributtes)
elsif @resource.class.reflections[@resource_relation].macro == :has_one
@relation = @resource.send("build_#{resource_relation}", relation_attributtes)
else
@relation = @resource.send(@resource_relation).build(relation_attributtes)
end
# Refactor
@relation = if @resource.respond_to?(:images) &&
((@attachment.present? && !@attachment.content_type.match(/pdf/)) || @cached_attachment.present?)
@resource.images.send("build", relation_attributtes)
elsif @resource.class.reflections[@resource_relation].macro == :has_one
@resource.send("build_#{resource_relation}", relation_attributtes)
else
@resource.send(@resource_relation).build(relation_attributtes)
end
@relation.user = user
end
@@ -50,7 +50,7 @@ class DirectUpload
def parent_resource_attachment_validations
@relation.valid?
if @relation.errors.has_key? :attachment
if @relation.errors.key? :attachment
errors[:attachment] = @relation.errors[:attachment]
end
end

View File

@@ -44,7 +44,7 @@ class Document < ActiveRecord::Base
attachment.instance.prefix(attachment, style)
end
def prefix(attachment, style)
def prefix(attachment, _style)
if !attachment.instance.persisted?
"cached_attachments/user/#{attachment.instance.user_id}"
else

View File

@@ -5,7 +5,7 @@ class Image < ActiveRecord::Base
TITLE_LEGHT_RANGE = 4..80
MIN_SIZE = 475
MAX_IMAGE_SIZE = 1.megabyte
ACCEPTED_CONTENT_TYPE = %w(image/jpeg image/jpg)
ACCEPTED_CONTENT_TYPE = %w(image/jpeg image/jpg).freeze
has_attached_file :attachment, styles: { large: "x#{MIN_SIZE}", medium: "300x300#", thumb: "140x245#" },
url: "/system/:class/:prefix/:style/:hash.:extension",
@@ -52,7 +52,7 @@ class Image < ActiveRecord::Base
attachment.instance.prefix(attachment, style)
end
def prefix(attachment, style)
def prefix(attachment, _style)
if !attachment.instance.persisted?
"cached_attachments/user/#{attachment.instance.user_id}"
else
@@ -103,8 +103,8 @@ class Image < ActiveRecord::Base
def remove_cached_attachment
image = Image.new(imageable: imageable,
cached_attachment: cached_attachment,
user: user)
cached_attachment: cached_attachment,
user: user)
image.set_attachment_from_cached_attachment
image.attachment.destroy
end

View File

@@ -9,9 +9,8 @@ class Poll::Answer < ActiveRecord::Base
validates :author, presence: true
validates :answer, presence: true
# temporary skipping validation, review when removing valid_answers
# validates :answer, inclusion: { in: ->(a) { a.question.valid_answers }},
# unless: ->(a) { a.question.blank? }
validates :answer, inclusion: { in: ->(a) { a.question.question_answers.pluck(:title) }},
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) }

View File

@@ -10,8 +10,9 @@ class Poll::PartialResult < ActiveRecord::Base
validates :question, presence: true
validates :author, presence: true
validates :answer, presence: true
validates :answer, inclusion: {in: ->(a) { a.question.valid_answers }}
validates :origin, inclusion: {in: VALID_ORIGINS}
validates :answer, inclusion: { in: ->(a) { a.question.question_answers.pluck(:title) }},
unless: ->(a) { a.question.blank? }
validates :origin, inclusion: { in: VALID_ORIGINS }
scope :by_author, ->(author_id) { where(author_id: author_id) }
scope :by_question, ->(question_id) { where(question_id: question_id) }

View File

@@ -39,17 +39,12 @@ class Poll::Question < ActiveRecord::Base
author_visible_name => 'C' }
end
def valid_answers
(super.try(:split, ',')&.compact || []).map(&:strip)
end
def copy_attributes_from_proposal(proposal)
if proposal.present?
self.author = proposal.author
self.author_visible_name = proposal.author.name
self.proposal_id = proposal.id
self.title = proposal.title
self.valid_answers = I18n.t('poll_questions.default_valid_answers')
end
end

125
app/models/poll/stats.rb Normal file
View File

@@ -0,0 +1,125 @@
class Poll
class Stats
def initialize(poll)
@poll = poll
end
def generate
stats = %w[total_participants total_participants_web total_web_valid total_web_white total_web_null
total_participants_booth total_booth_valid total_booth_white total_booth_null
total_valid_votes total_white_votes total_null_votes valid_percentage_web valid_percentage_booth
total_valid_percentage white_percentage_web white_percentage_booth total_white_percentage
null_percentage_web null_percentage_booth total_null_percentage total_participants_web_percentage
total_participants_booth_percentage]
stats.map { |stat_name| [stat_name.to_sym, send(stat_name)] }.to_h
end
private
def total_participants
total_participants_web + total_participants_booth
end
def total_participants_web
total_web_valid + total_web_white + total_web_null
end
def total_participants_web_percentage
(total_participants) == 0 ? 0 : total_participants_web * 100 / total_participants
end
def total_participants_booth
voters.where(origin: 'booth').count
end
def total_participants_booth_percentage
(total_participants) == 0 ? 0 : total_participants_booth * 100 / total_participants.to_f
end
def total_web_valid
voters.where(origin: 'web').count
end
def valid_percentage_web
(total_valid_votes) == 0 ? 0 : total_web_valid * 100 / total_valid_votes.to_f
end
def total_web_white
0
end
def white_percentage_web
0
end
def total_web_null
0
end
def null_percentage_web
0
end
def total_booth_valid
recounts.sum(:total_amount)
end
def valid_percentage_booth
(total_valid_votes) == 0 ? 0 : total_booth_valid * 100 / total_valid_votes.to_f
end
def total_booth_white
recounts.sum(:white_amount)
end
def white_percentage_booth
(total_white_votes) == 0 ? 0 : total_booth_white * 100 / total_white_votes.to_f
end
def total_booth_null
recounts.sum(:null_amount)
end
def null_percentage_booth
(total_null_votes == 0) ? 0 : total_booth_null * 100 / total_null_votes.to_f
end
def total_valid_votes
total_web_valid + total_booth_valid
end
def total_valid_percentage
(total_participants) == 0 ? 0 : total_valid_votes * 100 / total_participants.to_f
end
def total_white_votes
total_web_white + total_booth_white
end
def total_white_percentage
(total_participants) == 0 ? 0 : total_white_votes * 100 / total_participants.to_f
end
def total_null_votes
total_web_null + total_booth_null
end
def total_null_percentage
(total_participants) == 0 ? 0 : total_null_votes * 100 / total_participants.to_f
end
def voters
@poll.voters
end
def recounts
@poll.recounts
end
def stats_cache(key, &block)
Rails.cache.fetch("polls_stats/#{@poll.id}/#{key}/v7", &block)
end
end
end

View File

@@ -1,7 +1,7 @@
class Poll
class Voter < ActiveRecord::Base
VALID_ORIGINS = %w{ web booth }
VALID_ORIGINS = %w{web booth}.freeze
belongs_to :poll
belongs_to :user

View File

@@ -69,10 +69,10 @@ class Proposal < ActiveRecord::Base
scope :public_for_api, -> { all }
def self.recommendations(user)
tagged_with(user.interests, any: true).
where("author_id != ?", user.id).
unsuccessful.
not_followed_by_user(user)
tagged_with(user.interests, any: true)
.where("author_id != ?", user.id)
.unsuccessful
.not_followed_by_user(user)
end
def self.not_followed_by_user(user)

View File

@@ -37,11 +37,11 @@
</tr>
</thead>
<tbody>
<% question.valid_answers.each_with_index do |answer, i| %>
<% question.question_answers.each_with_index do |answer, i| %>
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
<tr id="question_<%= question.id %>_<%= i %>_result">
<td><%= answer %></td>
<td class="text-center"><%= by_answer[answer].present? ? by_answer[answer].sum(&:amount) : 0 %></td>
<td><%= answer.title %></td>
<td class="text-center"><%= by_answer[answer.title].present? ? by_answer[answer.title].sum(&:amount) : 0 %></td>
</tr>
<% end %>
</tbody>

View File

@@ -40,11 +40,11 @@
</tr>
</thead>
<tbody>
<% question.valid_answers.each_with_index do |answer, i| %>
<% question.question_answers.each_with_index do |answer, i| %>
<% by_answer = by_question[question.id].present? ? by_question[question.id].group_by(&:answer) : {} %>
<tr id="question_<%= question.id %>_<%= i %>_result">
<td><%= answer %></td>
<td><%= by_answer[answer].present? ? by_answer[answer].first.amount : 0 %></td>
<td><%= answer.title %></td>
<td><%= by_answer[answer.title].present? ? by_answer[answer.title].first.amount : 0 %></td>
</tr>
<% end %>
</tbody>

View File

@@ -12,24 +12,14 @@
</div>
</div>
<div class="row">
<div class="small-12 medium-6 column">
<label><%= t("officing.results.new.date") %></label>
<%= select_tag :date,
poll_dates_select_options(@poll),
{ prompt: t("officing.results.new.select_date"),
label: false } %>
</div>
</div>
<% @poll.questions.each do |question| %>
<div class="row">
<div class="small-12 column">
<h3><%= question.title %></h3>
</div>
<% question.valid_answers.each_with_index do |answer, i| %>
<% question.question_answers.each_with_index do |answer, i| %>
<div class="small-12 medium-6 large-3 column end">
<label><%= answer %></label>
<label><%= answer.title %></label>
<%= text_field_tag "questions[#{question.id}][#{i}]", answer_result_value(question.id, i), placeholder: "0" %>
</div>
<% end %>
@@ -101,4 +91,3 @@
</table>
<% end %>

View File

@@ -3,6 +3,5 @@
<strong><%= t("officing.voters.show.error_already_voted") %></strong>
</p>
</td>
<td class="text-center">
<small><%= t("officing.voters.show.no_actions") %></small>
<td>
</td>

View File

@@ -0,0 +1,20 @@
<div class="row">
<div class="small-12 column">
<ul class="tabs" data-tabs id="polls-tabs">
<li class="tabs-title">
<%= link_to "#tab-stats" do %>
<h3>
<%= t("polls.show.stats_menu") %> <!-- t("polls.show.comments_tab") -->
</h3>
<% end %>
</li>
<li class="tabs-title is-active">
<%= link_to "#tab-information" do %>
<h3>
<%= t("polls.show.info_menu") %>
</h3>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,126 @@
<div class="row margin">
<div class="small-12 medium-9 column">
<%= render "callout" %>
<% if @poll.voted_in_booth?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_booth") %>
</div>
<% else %>
<% if current_user && @poll.voted_in_web?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_web") %>
</div>
<% end %>
<% end %>
<% @questions.each do |question| %>
<%= render 'polls/questions/question', question: question, token: @token %>
<% end %>
<% if poll_voter_token(@poll, current_user).empty? %>
<div class="callout token-message js-token-message" style="display: none">
<%= t('poll_questions.show.voted_token') %>
</div>
<% end %>
<%= link_to t("polls.show.participate_in_other_polls"), polls_path, class: "button hollow" %>
</div>
</div>
<div class="expanded poll-more-info">
<div class="row margin">
<div class="small-12 medium-9 column">
<h3><%= t("polls.show.more_info_title") %></h3>
<%= safe_html_with_links simple_format(@poll.description) %>
</div>
<% if false %>
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t("polls.show.documents") %></h2>
</aside>
<% end %>
</div>
</div>
<div class="expanded poll-more-info-answers">
<div class="row padding">
<% @poll_questions_answers.each do |answer| %>
<div class="small-12 medium-6 column end answer <%= cycle('first', '') %>" id="answer_<%= answer.id %>">
<% if answer.description.present? %>
<h3><%= answer.title %></h3>
<% end %>
<% if answer.images.any? %>
<%= render "gallery", answer: answer %>
<% end %>
<% if answer.description.present? %>
<div class="margin-top">
<div id="answer_description_<%= answer.id %>" class="answer-description short" data-toggler="short">
<%= safe_html_with_links simple_format(answer.description) %>
</div>
<div class="margin">
<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>
<% end %>
<% if answer.documents.present? %>
<div class="document-link">
<p>
<span class="icon-document"></span>&nbsp;
<strong><%= t("polls.show.documents") %></strong>
</p>
<% answer.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
target: "_blank",
rel: "nofollow" %><br>
<% end %>
</div>
<% 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 %>
</div>
</div>
<div class="tabs-content" data-tabs-content="proposals-tabs" role="tablist">
<%= render "filter_subnav" %>
<div class="tabs-panel is-active" id="tab-comments">
<%= render "comments" %>
</div>
</div>

View File

@@ -28,131 +28,17 @@
</aside>
</div>
</div>
<div class="tabs-content" data-tabs-content="polls-tabs" role="tablist">
<%= render "results_subnavigation" %>
<div class="row margin">
<div class="small-12 medium-9 column">
<%= render "callout" %>
<% if @poll.voted_in_booth?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_booth") %>
</div>
<% else %>
<% if current_user && @poll.voted_in_web?(current_user) %>
<div class="callout warning">
<%= t("polls.show.already_voted_in_web") %>
</div>
<% end %>
<% end %>
<% @questions.each do |question| %>
<%= render 'polls/questions/question', question: question, token: @token %>
<% end %>
<% if poll_voter_token(@poll, current_user).empty? %>
<div class="callout token-message js-token-message" style="display: none">
<%= t('poll_questions.show.voted_token') %>
</div>
<% end %>
<%= link_to t("polls.show.participate_in_other_polls"), polls_path, class: "button hollow" %>
<div id="tab-stats" class="tabs-panel">
<%= render "polls/stats/show" %>
</div>
</div>
<div class="expanded poll-more-info">
<div class="row margin">
<div class="small-12 medium-9 column">
<h3><%= t("polls.show.more_info_title") %></h3>
<%= safe_html_with_links simple_format(@poll.description) %>
</div>
<% if false %>
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t("polls.show.documents") %></h2>
</aside>
<% end %>
</div>
</div>
<div class="expanded poll-more-info-answers">
<div class="row padding">
<% @poll_questions_answers.each do |answer| %>
<div class="small-12 medium-6 column end answer <%= cycle('first', '') %>" id="answer_<%= answer.id %>">
<% if answer.description.present? %>
<h3><%= answer.title %></h3>
<% end %>
<% if answer.images.any? %>
<%= render "gallery", answer: answer %>
<% end %>
<% if answer.description.present? %>
<div class="margin-top">
<div id="answer_description_<%= answer.id %>" class="answer-description short" data-toggler="short">
<%= safe_html_with_links simple_format(answer.description) %>
</div>
<div class="margin">
<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>
<% end %>
<% if answer.documents.present? %>
<div class="document-link">
<p>
<span class="icon-document"></span>&nbsp;
<strong><%= t("polls.show.documents") %></strong>
</p>
<% answer.documents.each do |document| %>
<%= link_to document.title,
document.attachment.url,
target: "_blank",
rel: "nofollow" %><br>
<% end %>
</div>
<% 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 %>
</div>
<div id="tab-information" class="tabs-panel is-active">
<%= render "show" %>
</div>
</div>
</div>
<div class="tabs-content" data-tabs-content="proposals-tabs" role="tablist">
<%= render "filter_subnav" %>
<div class="tabs-panel is-active" id="tab-comments">
<%= render "comments" %>
</div>
</div>

View File

@@ -0,0 +1,85 @@
<div class="row">
<div class="small-12 medium-3 column sidebar">
<p><%= t("polls.show.stats.title") %></p>
<ul class="menu vertical margin-top">
<li><a href="#total"><%= t("polls.show.stats.total_participation") %></a></li>
</ul>
</div>
<div class="small-12 medium-9 column">
<h3 id="total"><%= t("polls.show.stats.total_participation") %></h3>
<p class="stat-number margin-top">
<%= t("polls.show.stats.total_votes") %><br>
<span><%= @stats[:total_participants] %></span>
</p>
<table class="polls-total-stats">
<thead>
<tr>
<th scope="col"><%= t("polls.show.stats.votes") %></th>
<th scope="col"><%= t("polls.show.stats.web") %></th>
<th scope="col"><%= t("polls.show.stats.booth") %></th>
<th scope="col"><%= t("polls.show.stats.total") %></th>
</tr>
</thead>
<tbody>
<tr>
<th><%= t("polls.show.stats.valid") %></th>
<td><%= @stats[:total_web_valid] %> <small><em>
(<%= number_to_percentage(@stats[:valid_percentage_web],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_booth_valid] %> <small><em>
(<%= number_to_percentage(@stats[:valid_percentage_booth],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_valid_votes] %> <small><em>
(<%= number_to_percentage(@stats[:total_valid_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
</tr>
<tr>
<th><%= t("polls.show.stats.white") %></th>
<td><%= @stats[:total_web_white] %> <small><em>
(<%= number_to_percentage(@stats[:white_percentage_web],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_booth_white] %> <small><em>
(<%= number_to_percentage(@stats[:white_percentage_booth],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_white_votes] %> <small><em>
(<%= number_to_percentage(@stats[:total_white_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
</tr>
<tr>
<th><%= t("polls.show.stats.null_votes") %></th>
<td><%= @stats[:total_web_null] %> <small><em>
(<%= number_to_percentage(@stats[:null_percentage_web],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_booth_null] %> <small><em>
(<%= number_to_percentage(@stats[:null_percentage_booth],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_null_votes] %> <small><em>
(<%= number_to_percentage(@stats[:total_null_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
</tr>
<tr>
<th><%= t("polls.show.stats.total") %></th>
<td><%= @stats[:total_participants_web] %> <small><em>
(<%= number_to_percentage(@stats[:total_participants_web_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_participants_booth] %> <small><em>
(<%= number_to_percentage(@stats[:total_participants_booth_percentage],
strip_insignificant_zeros: true,
precision: 2) %>)</em></small></td>
<td><%= @stats[:total_participants_web] + @stats[:total_participants_booth] %></td>
</tr>
</tbody>
</table>
</div>
</div>

View File

@@ -156,7 +156,6 @@ en:
description: "Description"
poll/question:
title: "Question"
valid_answers: "Posibles answers"
summary: "Summary"
description: "Description"
external_url: "Link to additional documentation"

View File

@@ -498,9 +498,21 @@ en:
read_less: "Read less about %{answer}"
participate_in_other_polls: Participate in other polls
videos: "External video"
info_menu: "Information"
stats_menu: "Participation statistics"
stats:
title: "Participation data"
total_participation: "Total participation"
total_votes: "Total amount of given votes"
votes: "VOTES"
web: "WEB"
booth: "BOOTH"
total: "TOTAL"
valid: "Valid"
white: "White votes"
null_votes: "Invalid"
poll_questions:
create_question: "Create question"
default_valid_answers: "Yes, No"
show:
vote_answer: "Vote %{answer}"
voted: "You have voted %{answer}"

View File

@@ -21,14 +21,12 @@ en:
create: "Results saved"
error_create: "Results NOT saved. Error in data."
error_wrong_booth: "Wrong booth. Results NOT saved."
error_wrong_date: "Wrong date. Results NOT saved."
new:
title: "%{poll} - Add results"
not_allowed: "You are allowed to add results for this poll"
booth: "Booth"
date: "Date"
select_booth: "Select booth"
select_date: "Select date"
ballots_white: "Totally blank ballots"
ballots_null: "Invalid ballots"
ballots_total: "Total ballots"
@@ -63,7 +61,6 @@ en:
show:
can_vote: Can vote
error_already_voted: Has already participated in this poll
no_actions: There is no available actions
submit: Confirm vote
success: "Vote introduced!"
can_vote:

View File

@@ -150,7 +150,6 @@ es:
description: "Descripción"
poll/question:
title: "Pregunta"
valid_answers: "Posibles respuestas"
summary: "Resumen"
description: "Descripción"
external_url: "Enlace a documentación adicional"

View File

@@ -498,9 +498,21 @@ es:
read_less: "Leer menos sobre %{answer}"
participate_in_other_polls: Participar en otras votaciones
videos: "Vídeo externo"
info_menu: "Información"
stats_menu: "Estadísticas de participación"
stats:
title: "Datos de participación"
total_participation: "Participación total"
total_votes: "Nº total de votos emitidos"
votes: "VOTOS"
web: "WEB"
booth: "URNAS"
total: "TOTAL"
valid: "Válidos"
white: "En blanco"
null_votes: "Nulos"
poll_questions:
create_question: "Crear pregunta para votación"
default_valid_answers: "Sí, No"
show:
vote_answer: "Votar %{answer}"
voted: "Has votado %{answer}"

View File

@@ -21,14 +21,12 @@ es:
create: "Datos guardados"
error_create: "Resultados NO añadidos. Error en los datos"
error_wrong_booth: "Urna incorrecta. Resultados NO guardados."
error_wrong_date: "Fecha incorrecta. Resultados NO guardados."
new:
title: "%{poll} - Añadir resultados"
not_allowed: "No tienes permiso para introducir resultados"
booth: "Urna"
date: "Día"
select_booth: "Elige urna"
select_date: "Elige día"
ballots_white: "Papeletas totalmente en blanco"
ballots_null: "Papeletas nulas"
ballots_total: "Papeletas totales"
@@ -63,8 +61,7 @@ es:
show:
can_vote: Puede votar
error_already_voted: "Ya ha participado en esta votación"
no_actions: No hay acciones disponibles
submit: Confirmar voto
success: "¡Voto introducido!"
can_vote:
submit_disable_with: "Espera, confirmando voto..."
submit_disable_with: "Espera, confirmando voto..."

View File

@@ -111,7 +111,7 @@ Rails.application.routes.draw do
resources :annotations do
get :search, on: :collection
end
resources :polls, only: [:show, :index] do
get :results
resources :questions, controller: 'polls/questions', shallow: true do

View File

@@ -73,7 +73,7 @@ def create_user(email, username = Faker::Name.name)
confirmed_at: Time.current,
terms_of_service: "1",
gender: ['Male', 'Female'].sample,
date_of_birth: rand((Time.current - 80.years) .. (Time.current - 16.years)),
date_of_birth: rand((Time.current - 80.years)..(Time.current - 16.years)),
public_activity: (rand(1..100) > 30)
)
end
@@ -127,7 +127,7 @@ end
user = create_user("user#{i}@consul.dev")
level = [1, 2, 3].sample
if level >= 2
user.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: Faker::Number.number(10), document_type: "1", geozone: Geozone.reorder("RANDOM()").first)
user.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: Faker::Number.number(10), document_type: "1", geozone: Geozone.reorder("RANDOM()").first)
end
if level == 3
user.update(verified_at: Time.current, document_number: Faker::Number.number(10))
@@ -319,7 +319,7 @@ end
end
100.times do
voter = not_org_users.level_two_or_three_verified.reorder("RANDOM()").first
voter = not_org_users.level_two_or_three_verified.reorder("RANDOM()").first
proposal = Proposal.reorder("RANDOM()").first
proposal.vote_by(voter: voter, vote: true)
end
@@ -504,7 +504,7 @@ Proposal.last(3).each do |proposal|
"banner-img banner-img-three"].sample,
target_url: Rails.application.routes.url_helpers.proposal_path(proposal),
post_started_at: rand((Time.current - 1.week)..(Time.current - 1.day)),
post_ended_at: rand((Time.current - 1.day)..(Time.current + 1.week)),
post_ended_at: rand((Time.current - 1.day)..(Time.current + 1.week)),
created_at: rand((Time.current - 1.week)..Time.current))
end
@@ -561,13 +561,11 @@ print "Creating Poll Questions"
author = User.reorder("RANDOM()").first
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
open_at = rand(2.months.ago..2.months.from_now)
answers = Faker::Lorem.words((2..4).to_a.sample).map { |answer| answer.capitalize }
question = Poll::Question.create!(author: author,
title: Faker::Lorem.sentence(3).truncate(60),
valid_answers: answers.join(', '),
poll: poll)
answers.each do |answer|
Poll::Question::Answer.create!(question: question, title: answer, description: Faker::ChuckNorris.fact)
Faker::Lorem.words((2..4).to_a.sample).each do |answer|
Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact)
end
end
@@ -599,7 +597,10 @@ print "Creating Poll Questions from Proposals"
3.times do
proposal = Proposal.reorder("RANDOM()").first
poll = Poll.current.first
question = Poll::Question.create(valid_answers: "Yes, No", poll: poll)
question = Poll::Question.create(poll: poll)
Faker::Lorem.words((2..4).to_a.sample).each do |answer|
Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact)
end
question.copy_attributes_from_proposal(proposal)
question.save!
end
@@ -610,7 +611,10 @@ print "Creating Successful Proposals"
10.times do
proposal = Proposal.reorder("RANDOM()").first
poll = Poll.current.first
question = Poll::Question.create(valid_answers: "Yes, No", poll: poll)
question = Poll::Question.create(poll: poll)
Faker::Lorem.words((2..4).to_a.sample).each do |answer|
Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact)
end
question.copy_attributes_from_proposal(proposal)
question.save!
end
@@ -656,8 +660,7 @@ print "Creating legislation processes"
allegations_phase_enabled: true,
draft_publication_enabled: true,
result_publication_enabled: true,
published: true
)
published: true)
end
::Legislation::Process.all.each do |process|

View File

@@ -84,7 +84,7 @@ class CensusApi
end
def stubbed_response(document_type, document_number)
if document_number == "12345678Z" && document_type == "1"
if (document_number == "12345678Z" || document_number == "12345678Y") && document_type == "1"
stubbed_valid_response
else
stubbed_invalid_response

View File

@@ -503,7 +503,13 @@ FactoryGirl.define do
poll
association :author, factory: :user
sequence(:title) { |n| "Question title #{n}" }
valid_answers { Faker::Lorem.words(3).join(', ') }
trait :with_answers do
after(:create) do |question, _evaluator|
create(:poll_question_answer, question: question, title: "Yes")
create(:poll_question_answer, question: question, title: "No")
end
end
end
factory :poll_question_answer, class: 'Poll::Question::Answer' do
@@ -574,16 +580,16 @@ FactoryGirl.define do
end
factory :poll_answer, class: 'Poll::Answer' do
association :question, factory: :poll_question
association :question, factory: [:poll_question, :with_answers]
association :author, factory: [:user, :level_two]
answer { question.valid_answers.sample }
answer { question.question_answers.sample.title }
end
factory :poll_partial_result, class: 'Poll::PartialResult' do
association :question, factory: :poll_question
association :question, factory: [:poll_question, :with_answers]
association :author, factory: :user
origin { 'web' }
answer { question.valid_answers.sample }
answer { question.question_answers.sample.title }
end
factory :poll_recount, class: 'Poll::Recount' do

View File

@@ -30,9 +30,9 @@ feature 'Officer Assignments' do
expect(page).to have_content officer2.name
expect(page).to_not have_content officer3.name
end
end
end
scenario "Search", :js do
scenario "Search", :js do
poll = create(:poll)
booth = create(:poll_booth)
@@ -62,7 +62,6 @@ feature 'Officer Assignments' do
expect(page).to have_content officer2.name
expect(page).to_not have_content officer3.name
end
end
end
end

View File

@@ -261,8 +261,13 @@ feature 'Admin polls' do
booth_assignment_2 = create(:poll_booth_assignment, poll: poll)
booth_assignment_3 = create(:poll_booth_assignment, poll: poll)
question_1 = create(:poll_question, poll: poll, valid_answers: "Yes,No")
question_2 = create(:poll_question, poll: poll, valid_answers: "Today,Tomorrow")
question_1 = create(:poll_question, poll: poll)
create(:poll_question_answer, title: 'Yes', question: question_1)
create(:poll_question_answer, title: 'No', question: question_1)
question_2 = create(:poll_question, poll: poll)
create(:poll_question_answer, title: 'Today', question: question_2)
create(:poll_question_answer, title: 'Tomorrow', question: question_2)
[booth_assignment_1, booth_assignment_2, booth_assignment_3].each do |ba|
create(:poll_partial_result,
@@ -279,30 +284,32 @@ feature 'Admin polls' do
create(:poll_recount,
booth_assignment: booth_assignment_1,
white_amount: 21,
null_amount: 44)
null_amount: 44,
total_amount: 66)
visit admin_poll_path(poll)
click_link "Results"
expect(page).to have_content(question_1.title)
question_1.valid_answers.each_with_index do |answer, i|
question_1.question_answers.each_with_index do |answer, i|
within("#question_#{question_1.id}_#{i}_result") do
expect(page).to have_content(answer)
expect(page).to have_content(answer.title)
expect(page).to have_content([33, 0][i])
end
end
expect(page).to have_content(question_2.title)
question_2.valid_answers.each_with_index do |answer, i|
question_2.question_answers.each_with_index do |answer, i|
within("#question_#{question_2.id}_#{i}_result") do
expect(page).to have_content(answer)
expect(page).to have_content(answer.title)
expect(page).to have_content([0, 15][i])
end
end
within('#white_results') { expect(page).to have_content('21') }
within('#null_results') { expect(page).to have_content('44') }
within('#total_results') { expect(page).to have_content('66') }
end
end
end

View File

@@ -102,11 +102,11 @@ feature 'Admin shifts' do
shift2 = create(:poll_shift, :recount_scrutiny_task, officer: officer, booth: booth, date: Time.zone.tomorrow)
vote_collection_dates = (Date.current..poll.ends_at.to_date).to_a
.reject { |date| date == Time.zone.today }
.map { |date| I18n.l(date, format: :long) }
.reject { |date| date == Time.zone.today }
.map { |date| I18n.l(date, format: :long) }
recount_scrutiny_dates = (poll.ends_at.to_date..poll.ends_at.to_date + 1.week).to_a
.reject { |date| date == Time.zone.tomorrow }
.map { |date| I18n.l(date, format: :long) }
.reject { |date| date == Time.zone.tomorrow }
.map { |date| I18n.l(date, format: :long) }
visit available_admin_booths_path

View File

@@ -87,7 +87,6 @@ feature 'Admin settings' do
expect(page).to have_content "Map configuration updated succesfully"
end
end
end

View File

@@ -21,7 +21,7 @@ feature 'Commenting polls' do
end
scenario 'Show' do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
parent_comment = create(:comment, commentable: poll)
first_child = create(:comment, commentable: poll, parent: parent_comment)
@@ -243,7 +243,7 @@ feature 'Commenting polls' do
end
scenario "Flagging as inappropriate", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
comment = create(:comment, commentable: poll)
@@ -261,7 +261,7 @@ feature 'Commenting polls' do
end
scenario "Undoing flagging as inappropriate", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
comment = create(:comment, commentable: poll)
Flag.flag(user, comment)
@@ -280,7 +280,7 @@ feature 'Commenting polls' do
end
scenario "Flagging turbolinks sanity check", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
poll = create(:poll, title: "Should we change the world?")
comment = create(:comment, commentable: poll)
@@ -310,7 +310,7 @@ feature 'Commenting polls' do
feature "Moderators" do
scenario "can create comment as a moderator", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
moderator = create(:moderator)
@@ -330,7 +330,7 @@ feature 'Commenting polls' do
end
scenario "can create reply as a moderator", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
citizen = create(:user, username: "Ana")
manuela = create(:user, username: "Manuela")
@@ -359,7 +359,7 @@ feature 'Commenting polls' do
end
scenario "can not comment as an administrator" do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
moderator = create(:moderator)
@@ -372,7 +372,7 @@ feature 'Commenting polls' do
feature "Administrators" do
scenario "can create comment as an administrator", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
admin = create(:administrator)
@@ -392,7 +392,7 @@ feature 'Commenting polls' do
end
scenario "can create reply as an administrator", :js do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
citizen = create(:user, username: "Ana")
manuela = create(:user, username: "Manuela")
@@ -421,7 +421,7 @@ feature 'Commenting polls' do
end
scenario "can not comment as a moderator" do
skip "Feature not implemented yet, review soon"
skip "Feature not implemented yet, review soon"
admin = create(:administrator)

View File

@@ -394,7 +394,7 @@ feature 'Debates' do
end
scenario 'Debates are ordered by recommendations when there is a user logged', :js do
proposal = create(:proposal, tag_list: "Sport" )
proposal = create(:proposal, tag_list: "Sport")
user = create(:user)
create(:follow, followable: proposal, user: user)
login_as(user)
@@ -830,7 +830,7 @@ feature 'Debates' do
debate2 = create(:debate, title: "Show what you got", cached_votes_total: 1, tag_list: "Sport")
debate3 = create(:debate, title: "Do not display with same tag", cached_votes_total: 100, tag_list: "Sport")
debate4 = create(:debate, title: "Do not display", cached_votes_total: 1)
proposal1 = create(:proposal, tag_list: "Sport")
proposal1 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
visit debates_path

View File

@@ -408,7 +408,6 @@ feature 'Emails' do
end
expect(page).to have_content 'It will be done next week.'
email = open_last_email
expect(email).to have_subject('Someone has responded to your comment')
expect(email).to deliver_to(user1)

View File

@@ -27,7 +27,7 @@ feature "Home" do
background do
Setting['feature.user.recommendations'] = true
user = create(:user)
proposal = create(:proposal, tag_list: "Sport" )
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
login_as(user)
end

View File

@@ -7,8 +7,13 @@ feature 'Officing Results' do
@officer_assignment = create(:poll_officer_assignment, :final, officer: @poll_officer)
@poll = @officer_assignment.booth_assignment.poll
@poll.update(ends_at: 1.day.ago)
@question_1 = create(:poll_question, poll: @poll, valid_answers: "Yes,No")
@question_2 = create(:poll_question, poll: @poll, valid_answers: "Today,Tomorrow")
@question_1 = create(:poll_question, poll: @poll)
create(:poll_question_answer, title: 'Yes', question: @question_1)
create(:poll_question_answer, title: 'No', question: @question_1)
@question_2 = create(:poll_question, poll: @poll)
create(:poll_question_answer, title: 'Today', question: @question_2)
create(:poll_question_answer, title: 'Tomorrow', question: @question_2)
login_as(@poll_officer.user)
end
@@ -53,9 +58,7 @@ feature 'Officing Results' do
expect(page).to_not have_content('Your results')
booth_name = @officer_assignment.booth_assignment.booth.name
date = I18n.l(@poll.starts_at.to_date, format: :long)
select booth_name, from: 'officer_assignment_id'
select date, from: 'date'
fill_in "questions[#{@question_1.id}][0]", with: '100'
fill_in "questions[#{@question_1.id}][1]", with: '200'
@@ -71,8 +74,8 @@ feature 'Officing Results' do
expect(page).to have_content('Your results')
within("#results_#{@officer_assignment.booth_assignment_id}_#{@poll.starts_at.to_date.strftime('%Y%m%d')}") do
expect(page).to have_content(date)
within("#results_#{@officer_assignment.booth_assignment_id}_#{Date.current.strftime('%Y%m%d')}") do
expect(page).to have_content(I18n.l(Date.current, format: :long))
expect(page).to have_content(booth_name)
end
end
@@ -81,9 +84,9 @@ feature 'Officing Results' do
partial_result = create(:poll_partial_result,
officer_assignment: @officer_assignment,
booth_assignment: @officer_assignment.booth_assignment,
date: @poll.starts_at,
date: Date.current,
question: @question_1,
answer: @question_1.valid_answers[0],
answer: @question_1.question_answers.first.title,
author: @poll_officer.user,
amount: 7777)
@@ -94,9 +97,7 @@ feature 'Officing Results' do
visit new_officing_poll_result_path(@poll)
booth_name = partial_result.booth_assignment.booth.name
date = I18n.l(partial_result.date, format: :long)
select booth_name, from: 'officer_assignment_id'
select date, from: 'date'
fill_in "questions[#{@question_1.id}][0]", with: '5555'
fill_in "questions[#{@question_1.id}][1]", with: '200'
@@ -143,13 +144,13 @@ feature 'Officing Results' do
expect(page).to have_content(@officer_assignment.booth_assignment.booth.name)
expect(page).to have_content(@question_1.title)
@question_1.valid_answers.each_with_index do |answer, i|
within("#question_#{@question_1.id}_#{i}_result") { expect(page).to have_content(answer) }
@question_1.question_answers.each_with_index do |answer, i|
within("#question_#{@question_1.id}_#{i}_result") { expect(page).to have_content(answer.title) }
end
expect(page).to have_content(@question_2.title)
@question_2.valid_answers.each_with_index do |answer, i|
within("#question_#{@question_2.id}_#{i}_result") { expect(page).to have_content(answer) }
@question_2.question_answers.each_with_index do |answer, i|
within("#question_#{@question_2.id}_#{i}_result") { expect(page).to have_content(answer.title) }
end
within('#white_results') { expect(page).to have_content('21') }

View File

@@ -107,7 +107,7 @@ feature 'Poll Officing' do
expect(page).to_not have_css('#moderation_menu')
end
scenario 'Officing dashboard available for multiple sessions' do
scenario 'Officing dashboard available for multiple sessions', :js do
poll = create(:poll)
booth = create(:poll_booth)
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
@@ -117,6 +117,9 @@ feature 'Poll Officing' do
officer1 = create(:poll_officer, user: user1)
officer2 = create(:poll_officer, user: user2)
create(:poll_shift, officer: officer1, booth: booth, date: Date.current, task: :vote_collection)
create(:poll_shift, officer: officer2, booth: booth, date: Date.current, task: :vote_collection)
officer_assignment_1 = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer1)
officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment, officer: officer2)
@@ -134,7 +137,14 @@ feature 'Poll Officing' do
page.should have_content("Here you can validate user documents and store voting results")
visit new_officing_residence_path
page.should have_content("Validate document")
select 'DNI', from: 'residence_document_type'
fill_in 'residence_document_number', with: "12345678Z"
fill_in 'residence_year_of_birth', with: '1980'
click_button 'Validate document'
expect(page).to have_content 'Document verified with Census'
click_button "Confirm vote"
expect(page).to have_content "Vote introduced!"
expect(Poll::Voter.where(document_number: '12345678Z', poll_id: poll, origin: 'booth', officer_id: officer1).count).to be(1)
visit final_officing_polls_path
page.should have_content("Polls ready for final recounting")
@@ -144,7 +154,14 @@ feature 'Poll Officing' do
page.should have_content("Here you can validate user documents and store voting results")
visit new_officing_residence_path
page.should have_content("Validate document")
select 'DNI', from: 'residence_document_type'
fill_in 'residence_document_number', with: "12345678Y"
fill_in 'residence_year_of_birth', with: '1980'
click_button 'Validate document'
expect(page).to have_content 'Document verified with Census'
click_button "Confirm vote"
expect(page).to have_content "Vote introduced!"
expect(Poll::Voter.where(document_number: '12345678Y', poll_id: poll, origin: 'booth', officer_id: officer2).count).to be(1)
visit final_officing_polls_path
page.should have_content("Polls ready for final recounting")

View File

@@ -367,4 +367,17 @@ feature 'Polls' do
end
end
context "Results and stats" do
scenario "See polls statistics", :js do
user = create(:user)
poll = create(:poll, summary: "Summary", description: "Description")
login_as user
visit poll_path(poll)
click_link "Participation statistics"
expect(page).to have_content("Total participation")
end
end
end

View File

@@ -147,10 +147,36 @@ feature "Voter" do
expect(page).to have_link('Yes')
expect(page).to have_link('No')
end
end
end
scenario "Voting in poll and then verifiying account", :js do
user = create(:user)
question = create(:poll_question, poll: poll)
answer1 = create(:poll_question_answer, question: question, title: 'Yes')
answer2 = create(:poll_question_answer, question: question, title: 'No')
login_through_form_as_officer(officer.user)
vote_for_poll_via_booth
visit root_path
click_link "Sign out"
login_as user
visit account_path
click_link 'Verify my account'
verify_residence
confirm_phone(user)
visit poll_path(poll)
expect(page).to_not have_link('Yes')
expect(page).to have_content "You have already participated in a physical booth. You can not participate again."
expect(Poll::Voter.count).to eq(1)
end
end
end

View File

@@ -725,10 +725,10 @@ describe Debate do
end
it "Should return debates ordered by cached_votes_total" do
debate1 = create(:debate, cached_votes_total: 1, tag_list: "Sport" )
debate2 = create(:debate, cached_votes_total: 5, tag_list: "Sport" )
debate3 = create(:debate, cached_votes_total: 10, tag_list: "Sport" )
proposal = create(:proposal, tag_list: "Sport" )
debate1 = create(:debate, cached_votes_total: 1, tag_list: "Sport")
debate2 = create(:debate, cached_votes_total: 5, tag_list: "Sport")
debate3 = create(:debate, cached_votes_total: 10, tag_list: "Sport")
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
result = Debate.recommendations(user).sort_by_recommendations
@@ -741,7 +741,7 @@ describe Debate do
it "Should return debates related with user interests" do
debate1 = create(:debate, tag_list: "Sport")
debate2 = create(:debate, tag_list: "Politics")
proposal1 = create(:proposal, tag_list: "Sport")
proposal1 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal1, user: user)
result = Debate.recommendations(user)
@@ -753,7 +753,7 @@ describe Debate do
it "Should not return debates when user is the author" do
debate1 = create(:debate, author: user, tag_list: "Sport")
debate2 = create(:debate, tag_list: "Sport")
proposal = create(:proposal, tag_list: "Sport" )
proposal = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal, user: user)
result = Debate.recommendations(user)

View File

@@ -42,7 +42,7 @@ describe DirectUpload do
proposal_document_direct_upload.save_attachment
expect(File.exists?(proposal_document_direct_upload.relation.attachment.path)).to eq(true)
expect(File.exist?(proposal_document_direct_upload.relation.attachment.path)).to eq(true)
expect(proposal_document_direct_upload.relation.attachment.path).to include('cached_attachments')
end
@@ -57,7 +57,7 @@ describe DirectUpload do
uploaded_path = proposal_document_direct_upload.relation.attachment.path
proposal_document_direct_upload.destroy_attachment
expect(File.exists?(uploaded_path)).to eq(false)
expect(File.exist?(uploaded_path)).to eq(false)
end
end

View File

@@ -2,7 +2,7 @@ require 'rails_helper'
describe MapLocation do
let(:map_location) { build(:map_location, :proposal_map_location ) }
let(:map_location) { build(:map_location, :proposal_map_location) }
it "should be valid" do
expect(map_location).to be_valid

View File

@@ -25,9 +25,12 @@ describe Poll::Answer do
expect(answer).to_not be_valid
end
it "should be valid for answers included in the Poll::Question's list" do
skip "review when removing valid_answers"
question = create(:poll_question, valid_answers: 'One, Two, Three')
it "should be valid for answers included in the Poll::Question's question_answers list" do
question = create(:poll_question)
create(:poll_question_answer, title: 'One', question: question)
create(:poll_question_answer, title: 'Two', question: question)
create(:poll_question_answer, title: 'Three', question: question)
expect(build(:poll_answer, question: question, answer: 'One')).to be_valid
expect(build(:poll_answer, question: question, answer: 'Two')).to be_valid
expect(build(:poll_answer, question: question, answer: 'Three')).to be_valid
@@ -40,7 +43,7 @@ describe Poll::Answer do
let(:author) { create(:user, :level_two) }
let(:poll) { create(:poll) }
let(:question) { create(:poll_question, poll: poll, valid_answers: "Yes, No") }
let(:question) { create(:poll_question, :with_answers, poll: poll) }
it "creates a poll_voter with user and poll data" do
answer = create(:poll_answer, question: question, author: author, answer: "Yes")

View File

@@ -4,12 +4,16 @@ describe Poll::PartialResult do
describe "validations" do
it "validates that the answers are included in the Poll::Question's list" do
q = create(:poll_question, valid_answers: 'One, Two, Three')
expect(build(:poll_partial_result, question: q, answer: 'One')).to be_valid
expect(build(:poll_partial_result, question: q, answer: 'Two')).to be_valid
expect(build(:poll_partial_result, question: q, answer: 'Three')).to be_valid
question = create(:poll_question)
create(:poll_question_answer, title: 'One', question: question)
create(:poll_question_answer, title: 'Two', question: question)
create(:poll_question_answer, title: 'Three', question: question)
expect(build(:poll_partial_result, question: q, answer: 'Four')).to_not be_valid
expect(build(:poll_partial_result, question: question, answer: 'One')).to be_valid
expect(build(:poll_partial_result, question: question, answer: 'Two')).to be_valid
expect(build(:poll_partial_result, question: question, answer: 'Three')).to be_valid
expect(build(:poll_partial_result, question: question, answer: 'Four')).to_not be_valid
end
end
@@ -57,24 +61,24 @@ describe Poll::PartialResult do
expect(partial_result.amount_log).to eq("")
expect(partial_result.author_id_log).to eq("")
author_A = create(:poll_officer).user
author_B = create(:poll_officer).user
author_C = create(:poll_officer).user
author1 = create(:poll_officer).user
author2 = create(:poll_officer).user
author3 = create(:poll_officer).user
partial_result.amount = 33
partial_result.author_id = author_A.id
partial_result.author_id = author1.id
partial_result.save!
partial_result.amount = 32
partial_result.author_id = author_B.id
partial_result.author_id = author2.id
partial_result.save!
partial_result.amount = 34
partial_result.author_id = author_C.id
partial_result.author_id = author3.id
partial_result.save!
expect(partial_result.amount_log).to eq(":33:32")
expect(partial_result.author_id_log).to eq(":#{author_A.id}:#{author_B.id}")
expect(partial_result.author_id_log).to eq(":#{author1.id}:#{author2.id}")
end
end

View File

@@ -3,13 +3,6 @@ require 'rails_helper'
RSpec.describe Poll::Question, type: :model do
let(:poll_question) { build(:poll_question) }
describe "#valid_answers" do
it "gets a comma-separated string, but returns an array" do
poll_question.valid_answers = "Yes, No"
expect(poll_question.valid_answers).to eq(["Yes", "No"])
end
end
describe "#poll_question_id" do
it "should be invalid if a poll is not selected" do
poll_question.poll_id = nil
@@ -27,7 +20,6 @@ RSpec.describe Poll::Question, type: :model do
create_list(:geozone, 3)
p = create(:proposal)
poll_question.copy_attributes_from_proposal(p)
expect(poll_question.valid_answers).to eq(['Yes', 'No'])
expect(poll_question.author).to eq(p.author)
expect(poll_question.author_visible_name).to eq(p.author.name)
expect(poll_question.proposal_id).to eq(p.id)

View File

@@ -0,0 +1,45 @@
require 'rails_helper'
describe Poll::Stats do
describe "Calculate stats" do
it "Generate the correct stats" do
poll = create(:poll)
booth = create(:poll_booth)
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
create(:poll_voter, poll: poll, origin: 'web')
3.times {create(:poll_voter, poll: poll, origin: 'booth')}
create(:poll_voter, poll: poll)
create(:poll_recount, origin: 'booth', white_amount: 1, null_amount: 0, total_amount: 2, booth_assignment_id: booth_assignment.id)
stats = Poll::Stats.new(poll).generate
expect(stats[:total_participants]).to eq(5)
expect(stats[:total_participants_web]).to eq(2)
expect(stats[:total_participants_booth]).to eq(3)
expect(stats[:total_valid_votes]).to eq(4)
expect(stats[:total_white_votes]).to eq(1)
expect(stats[:total_null_votes]).to eq(0)
expect(stats[:total_web_valid]).to eq(2)
expect(stats[:total_web_white]).to eq(0)
expect(stats[:total_web_null]).to eq(0)
expect(stats[:total_booth_valid]).to eq(2)
expect(stats[:total_booth_white]).to eq(1)
expect(stats[:total_booth_null]).to eq(0)
expect(stats[:total_participants_web_percentage]).to eq(40)
expect(stats[:total_participants_booth_percentage]).to eq(60)
expect(stats[:valid_percentage_web]).to eq(50)
expect(stats[:white_percentage_web]).to eq(0)
expect(stats[:null_percentage_web]).to eq(0)
expect(stats[:valid_percentage_booth]).to eq(50)
expect(stats[:white_percentage_booth]).to eq(100)
expect(stats[:null_percentage_booth]).to eq(0)
expect(stats[:total_valid_percentage]).to eq(80)
expect(stats[:total_white_percentage]).to eq(20)
expect(stats[:total_null_percentage]).to eq(0)
end
end
end

View File

@@ -903,10 +903,10 @@ describe Proposal do
end
it "Should return proposals ordered by cached_votes_up" do
proposal1 = create(:proposal, cached_votes_up: 1, tag_list: "Sport" )
proposal2 = create(:proposal, cached_votes_up: 5, tag_list: "Sport" )
proposal3 = create(:proposal, cached_votes_up: 10, tag_list: "Sport" )
proposal4 = create(:proposal, tag_list: "Sport" )
proposal1 = create(:proposal, cached_votes_up: 1, tag_list: "Sport")
proposal2 = create(:proposal, cached_votes_up: 5, tag_list: "Sport")
proposal3 = create(:proposal, cached_votes_up: 10, tag_list: "Sport")
proposal4 = create(:proposal, tag_list: "Sport")
create(:follow, followable: proposal4, user: user)
result = Proposal.recommendations(user).sort_by_recommendations

View File

@@ -2,7 +2,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
include ActionView::Helpers
let!(:user) { create(:user, :level_two) }
let!(:user) { create(:user, :level_two) }
before do
Setting['feature.map'] = true
@@ -11,7 +11,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
describe "At #{mappable_new_path}" do
let!(:arguments) { {} }
let!(:mappable) { create("#{mappable_factory_name}".to_sym) }
let!(:mappable) { create(mappable_factory_name.to_s.to_sym) }
let!(:map_location) { create(:map_location, "#{mappable_factory_name}_map_location".to_sym, "#{mappable_association_name}": mappable) }
before { set_arguments(arguments, mappable, mappable_path_arguments) }
@@ -77,10 +77,10 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
describe "At #{mappable_edit_path}" do
let!(:mappable) { create("#{mappable_factory_name}".to_sym) }
let!(:mappable) { create(mappable_factory_name.to_s.to_sym) }
let!(:map_location) { create(:map_location, "#{mappable_factory_name}_map_location".to_sym, "#{mappable_association_name}": mappable) }
before { skip } unless mappable_edit_path.present?
before { skip } if mappable_edit_path.blank?
scenario "Should edit map on #{mappable_factory_name} and contain default values", :js do
login_as mappable.author
@@ -143,13 +143,13 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
describe "At #{mappable_show_path}" do
let!(:arguments) { {} }
let!(:mappable) { create("#{mappable_factory_name}".to_sym) }
let!(:mappable) { create(mappable_factory_name.to_s.to_sym) }
let!(:map_location) { create(:map_location, "#{mappable_factory_name}_map_location".to_sym, "#{mappable_association_name}": mappable) }
before { set_arguments(arguments, mappable, mappable_path_arguments) }
scenario "Should display map on #{mappable_factory_name} show page", :js do
arguments.merge!("id": mappable.id)
arguments[:id] = mappable.id
visit send(mappable_show_path, arguments)
@@ -157,9 +157,9 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
end
scenario "Should not display map on #{mappable_factory_name} show when marker is not defined", :js do
mappable_without_map = create("#{mappable_factory_name}".to_sym)
mappable_without_map = create(mappable_factory_name.to_s.to_sym)
set_arguments(arguments, mappable_without_map, mappable_path_arguments)
arguments.merge!("id": mappable_without_map.id)
arguments[:id] = mappable_without_map.id
visit send(mappable_show_path, arguments)
@@ -168,7 +168,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
scenario "Should not display map on #{mappable_factory_name} show page when feature.map is disable", :js do
Setting['feature.map'] = false
arguments.merge!("id": mappable.id)
arguments[:id] = mappable.id
visit send(mappable_show_path, arguments)
@@ -212,9 +212,7 @@ def submit_budget_investment_form
end
def set_arguments(arguments, mappable, mappable_path_arguments)
if mappable_path_arguments
mappable_path_arguments.each do |argument_name, path_to_value|
mappable_path_arguments&.each do |argument_name, path_to_value|
arguments.merge!("#{argument_name}": mappable.send(path_to_value))
end
end
end

View File

@@ -199,8 +199,8 @@ shared_examples "nested documentable" do |login_as_name, documentable_factory_na
find("#tab-documents-label").click
expect(page).to have_content "empty.pdf"
#Review
#Doble check why the file is stored with a name different to empty.pdf
# Review
# Doble check why the file is stored with a name different to empty.pdf
expect(page).to have_css("a[href$='.pdf']")
end

View File

@@ -1,4 +1,4 @@
shared_examples "nested imageable" do |imageable_factory_name, path, imageable_path_arguments, fill_resource_method_name, submit_button, imageable_success_notice, has_many_images=false|
shared_examples "nested imageable" do |imageable_factory_name, path, imageable_path_arguments, fill_resource_method_name, submit_button, imageable_success_notice, has_many_images = false|
include ActionView::Helpers
include ImagesHelper
include ImageablesHelper
@@ -9,15 +9,11 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
let!(:imageable) { create(imageable_factory_name) }
before do
if imageable_path_arguments
imageable_path_arguments.each do |argument_name, path_to_value|
imageable_path_arguments&.each do |argument_name, path_to_value|
arguments.merge!("#{argument_name}": imageable.send(path_to_value))
end
end
if imageable.respond_to?(:author)
imageable.update(author: user)
end
imageable.update(author: user) if imageable.respond_to?(:author)
end
describe "at #{path}" do
@@ -119,7 +115,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
click_on submit_button
if has_many_images
#Pending. Review soon and test
# Pending. Review soon and test
else
within "#nested-image .image" do
expect(page).to have_content("can't be blank", count: 2)
@@ -174,7 +170,7 @@ shared_examples "nested imageable" do |imageable_factory_name, path, imageable_p
imageable_redirected_to_resource_show_or_navigate_to
if has_many_images
#Pending. Review soon and test
# Pending. Review soon and test
else
expect(page).to have_selector "figure img"
expect(page).to have_selector "figure figcaption"
@@ -230,7 +226,7 @@ rescue
return
end
def imageable_attach_new_file(imageable_factory_name, path, success = true)
def imageable_attach_new_file(_imageable_factory_name, path, success = true)
click_link "Add image"
within "#nested-image" do
image = find(".image")

View File

@@ -163,14 +163,15 @@ module CommonActions
expect(page).to have_content 'Document verified with Census'
end
def confirm_phone
def confirm_phone(user = nil)
user ||= User.last
fill_in 'sms_phone', with: "611111111"
click_button 'Send'
expect(page).to have_content 'Enter the confirmation code sent to you by text message'
user = User.last.reload
fill_in 'sms_confirmation_code', with: user.sms_confirmation_code
fill_in 'sms_confirmation_code', with: user.reload.sms_confirmation_code
click_button 'Send'
expect(page).to have_content 'Code correct'