Merge branch 'master' into proposal-dashboard
This commit is contained in:
@@ -22,10 +22,11 @@ env:
|
||||
global:
|
||||
- KNAPSACK_PRO_FIXED_QUEUE_SPLIT=true
|
||||
- KNAPSACK_PRO_LOG_LEVEL=info
|
||||
- KNAPSACK_PRO_CI_NODE_TOTAL=2
|
||||
- KNAPSACK_PRO_CI_NODE_TOTAL=3
|
||||
matrix:
|
||||
- KNAPSACK_PRO_CI_NODE_INDEX=0
|
||||
- KNAPSACK_PRO_CI_NODE_INDEX=1
|
||||
- KNAPSACK_PRO_CI_NODE_INDEX=2
|
||||
notifications:
|
||||
slack:
|
||||
secure: 18E9SU0SR/9knRvCMYwVqFCqVTBT6qJtZQ/gadpheqUPPlcLoQfnlIzJkLIYqkE0sn1nkBE5Bt2I90FU53p0NkrTEmSGlQXcN1vEXM8EXMaoVf3NBsIJeleMwt9VTojzo81EgIi6x7q3fDiFORJ4rqOGd9XkeLn5yrAtIkdaenVs0bhS5s24FP76hKqO37IFLG2v3EEqxg5k31oW6yhyP35Mxns+AGbfaZbxEy4XbCoU65KFuYhBsVZ/y1evOl/wcre2fCAoT2uKeqUWGEcDzH7oSCz7vfk7iO9BZnO++v7oj8mr/nrZL1KMFt77eqtdT51XQoJcchgJC/R9km5hRGkQqFCHhqPcBxo5c3p+jauL0kLaqTggeLDv2FQ2huJ8FSJ4ADac+n3g7wT7BX7HJlCvK0nbooY1JtBlk7+6/pw6ksSFIOo0FHg5gXN9IlG1tQQuENzzsXULNc6s4nPeT+n78uOp1b0N/Gn06moEBaKgXqqx1yV1XeJ02X8n3uDZxPuX3n2bJ4DMIrBjeWApxHAgyOraOzQHNQgJoj4tHlWutF33ApV2tcIMefIzvjM4tIYwIkpfGgohGaTf8eU5X9pqiMgwlDpJHVBsSvpk/Z/Nj7evYznjBiDYqOcXoztsqHrS0C91MaT+eExDfd9HDmThsE07RT7zcP9aElFZA/k=
|
||||
|
||||
20
README.md
20
README.md
@@ -1,3 +1,9 @@
|
||||
<!--
|
||||
Title: CONSUL
|
||||
Description: Citizen Participation and Open Government Application
|
||||
Keywords: democracy, citizen participation, eparticipation, debates, proposals, voting, consultations, crowdlaw, participatory budgeting
|
||||
-->
|
||||
|
||||

|
||||
|
||||
# CONSUL
|
||||
@@ -19,13 +25,17 @@ Citizen Participation and Open Government Application
|
||||
|
||||
This is the opensource code repository of the eParticipation website CONSUL, originally developed for the Madrid City government eParticipation website
|
||||
|
||||
## Current state
|
||||
## Documentation
|
||||
|
||||
Development started on [2015 July 15th](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6). Code was deployed to production on 2015 september 7th to [decide.madrid.es](https://decide.madrid.es). Since then new features are added often. You can take a look at the current features at the [project's website](http://consulproject.org/) and future features at the [Roadmap](https://github.com/consul/consul/projects/6) and [open issues list](https://github.com/consul/consul/issues).
|
||||
Check the ongoing documentation at [https://docs.consulproject.org](https://docs.consulproject.org) to learn more about how to start your own CONSUL fork, install it, customize it and learn to use it from an administrator/maintainer perspective.
|
||||
|
||||
## CONSUL Project main website
|
||||
|
||||
You can access the main website of the project at [http://consulproject.org](http://consulproject.org) where you can find documentation about the use of the platform, videos, and links to the community space.
|
||||
|
||||
## Configuration for development and test environments
|
||||
|
||||
**NOTE**: For more detailed instructions check the [docs](https://consul_docs.gitbooks.io/docs/)
|
||||
**NOTE**: For more detailed instructions check the [docs](https://docs.consulproject.org)
|
||||
|
||||
Prerequisites: install git, Ruby 2.3.2, `bundler` gem, Node.js and PostgreSQL (>=9.4).
|
||||
|
||||
@@ -69,9 +79,9 @@ But for some actions like voting, you will need a verified user, the seeds file
|
||||
|
||||
See [installer](https://github.com/consul/installer)
|
||||
|
||||
## Documentation
|
||||
## Current state
|
||||
|
||||
Check the ongoing documentation at [https://consul_docs.gitbooks.io/docs/content/](https://consul_docs.gitbooks.io/docs/content/) to learn more about how to start your own CONSUL fork, install it, customize it and learn to use it from an administrator/maintainer perspective. You can contribute to it at [https://github.com/consul/docs](https://github.com/consul/docs)
|
||||
Development started on [2015 July 15th](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6). Code was deployed to production on 2015 september 7th to [decide.madrid.es](https://decide.madrid.es). Since then new features are added often. You can take a look at the current features at the [project's website](http://consulproject.org/) and future features at the [Roadmap](https://github.com/consul/consul/projects/6) and [open issues list](https://github.com/consul/consul/issues).
|
||||
|
||||
## License
|
||||
|
||||
|
||||
20
README_ES.md
20
README_ES.md
@@ -1,3 +1,9 @@
|
||||
<!--
|
||||
Title: CONSUL
|
||||
Description: Aplicación de Participación Ciudadana y Gobierno Abierto
|
||||
Keywords: democracia, participación ciudadana, participación electrónica, debates, propuestas, votaciones, consultas, legislación colaborativa, presupuestos participativos
|
||||
-->
|
||||
|
||||

|
||||
|
||||
# CONSUL
|
||||
@@ -18,13 +24,17 @@ Aplicación de Participación Ciudadana y Gobierno Abierto
|
||||
|
||||
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana CONSUL, creada originariamente por el Ayuntamiento de Madrid.
|
||||
|
||||
## Estado del proyecto
|
||||
## Documentación
|
||||
|
||||
El desarrollo de esta aplicación comenzó el [15 de Julio de 2015](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6) y el código fue puesto en producción el día 7 de Septiembre de 2015 en [decide.madrid.es](https://decide.madrid.es). Desde entonces se le añaden mejoras y funcionalidades constantemente. Las funcionalidades actuales se pueden consultar en la [la página del projecto](http://consulproject.org/es) y las futuras funcionalidades en el [Roadmap](https://github.com/consul/consul/projects/6) y [el listado de issues](https://github.com/consul/consul/issues).
|
||||
Por favor visita la documentación que está siendo completada en [https://docs.consulproject.org](https://docs.consulproject.org) para conocer más sobre este proyecto, cómo comenzar tu propio fork, instalarlo, personalizarlo y usarlo como administrador/mantenedor.
|
||||
|
||||
## Web CONSUL Project
|
||||
|
||||
Puedes acceder a la página principal del proyecto en [http://consulproject.org](http://consulproject.org) donde puedes encontrar documentación sobre el uso de la plataforma, videos y enlaces al espacio de la comunidad.
|
||||
|
||||
## Configuración para desarrollo y tests
|
||||
|
||||
**NOTA**: para unas instrucciones más detalladas consulta la [documentación](https://github.com/consul/docs/tree/master/es/getting_started/prerequisites)
|
||||
**NOTA**: para unas instrucciones más detalladas consulta la [documentación](https://docs.consulproject.org)
|
||||
|
||||
Prerequisitos: tener instalado git, Ruby 2.3.2, la gema `bundler`, Node.js y PostgreSQL (9.4 o superior).
|
||||
|
||||
@@ -64,9 +74,9 @@ Pero para ciertas acciones, como apoyar, necesitarás un usuario verificado, el
|
||||
**user:** verified@consul.dev
|
||||
**pass:** 12345678
|
||||
|
||||
## Documentación
|
||||
## Estado del proyecto
|
||||
|
||||
Por favor visita la documentación que está siendo completada en [https://consul_docs.gitbooks.io/docs/content/](https://consul_docs.gitbooks.io/docs/content/) para conocer más sobre este proyecto, como comenzar tu propio fork, instalarlo, customizarlo y usarlo como administrador/mantenedor. Puedes colaborar en ella en [https://github.com/consul/docs](https://github.com/consul/docs)
|
||||
El desarrollo de esta aplicación comenzó el [15 de Julio de 2015](https://github.com/consul/consul/commit/8db36308379accd44b5de4f680a54c41a0cc6fc6) y el código fue puesto en producción el día 7 de Septiembre de 2015 en [decide.madrid.es](https://decide.madrid.es). Desde entonces se le añaden mejoras y funcionalidades constantemente. Las funcionalidades actuales se pueden consultar en la [la página del projecto](http://consulproject.org/es) y las futuras funcionalidades en el [Roadmap](https://github.com/consul/consul/projects/6) y [el listado de issues](https://github.com/consul/consul/issues).
|
||||
|
||||
## Licencia
|
||||
|
||||
|
||||
@@ -1205,6 +1205,11 @@ table {
|
||||
.filter {
|
||||
display: inline-block;
|
||||
margin: 0 $line-height / 2;
|
||||
|
||||
label {
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.button {
|
||||
|
||||
@@ -1168,6 +1168,11 @@
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.confirmed {
|
||||
font-size: rem-calc(24);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info {
|
||||
background: #6a2a72;
|
||||
|
||||
|
||||
@@ -4,10 +4,8 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
|
||||
|
||||
feature_flag :budgets
|
||||
|
||||
has_orders %w{oldest}, only: [:show, :edit]
|
||||
has_filters(%w{all without_admin without_valuator under_valuation
|
||||
valuation_finished winners},
|
||||
only: [:index, :toggle_selection])
|
||||
has_orders %w[oldest], only: [:show, :edit]
|
||||
has_filters %w[all], only: [:index, :toggle_selection]
|
||||
|
||||
before_action :load_budget
|
||||
before_action :load_investment, only: [:show, :edit, :update, :toggle_selection]
|
||||
|
||||
@@ -23,7 +23,9 @@ class Admin::BudgetsController < Admin::BaseController
|
||||
def calculate_winners
|
||||
return unless @budget.balloting_process?
|
||||
@budget.headings.each { |heading| Budget::Result.new(@budget, heading).delay.calculate_winners }
|
||||
redirect_to admin_budget_budget_investments_path(budget_id: @budget.id, filter: "winners"),
|
||||
redirect_to admin_budget_budget_investments_path(
|
||||
budget_id: @budget.id,
|
||||
advanced_filters: ["winners"]),
|
||||
notice: I18n.t("admin.budgets.winners.calculated")
|
||||
end
|
||||
|
||||
|
||||
@@ -1,12 +1,46 @@
|
||||
class Officing::BaseController < ApplicationController
|
||||
layout "admin"
|
||||
helper_method :current_booth
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :verify_officer
|
||||
|
||||
skip_authorization_check
|
||||
|
||||
def verify_officer
|
||||
raise CanCan::AccessDenied unless current_user.try(:poll_officer?)
|
||||
end
|
||||
private
|
||||
|
||||
def verify_officer
|
||||
raise CanCan::AccessDenied unless current_user.try(:poll_officer?)
|
||||
end
|
||||
|
||||
def load_officer_assignment
|
||||
@officer_assignments ||= current_user.poll_officer.
|
||||
officer_assignments.
|
||||
voting_days.
|
||||
where(date: Time.current.to_date)
|
||||
end
|
||||
|
||||
def verify_officer_assignment
|
||||
if @officer_assignments.blank?
|
||||
redirect_to officing_root_path, notice: t("officing.residence.flash.not_allowed")
|
||||
end
|
||||
end
|
||||
|
||||
def verify_booth
|
||||
return unless current_booth.blank?
|
||||
booths = current_user.poll_officer.todays_booths
|
||||
case booths.count
|
||||
when 0
|
||||
redirect_to officing_root_path
|
||||
when 1
|
||||
session[:booth_id] = booths.first.id
|
||||
else
|
||||
redirect_to new_officing_booth_path
|
||||
end
|
||||
end
|
||||
|
||||
def current_booth
|
||||
Poll::Booth.where(id: session[:booth_id]).first
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
24
app/controllers/officing/booth_controller.rb
Normal file
24
app/controllers/officing/booth_controller.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
class Officing::BoothController < Officing::BaseController
|
||||
before_action :load_officer_assignment
|
||||
before_action :verify_officer_assignment
|
||||
|
||||
def new
|
||||
@booths = current_user.poll_officer.todays_booths
|
||||
end
|
||||
|
||||
def create
|
||||
set_booth(Poll::Booth.find(booth_params[:id]))
|
||||
redirect_to officing_root_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def booth_params
|
||||
params.require(:booth).permit(:id)
|
||||
end
|
||||
|
||||
def set_booth(booth)
|
||||
session[:booth_id] = booth.id
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
class Officing::PollsController < Officing::BaseController
|
||||
before_action :verify_booth
|
||||
|
||||
def index
|
||||
@polls = current_user.poll_officer? ? current_user.poll_officer.voting_days_assigned_polls : []
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
class Officing::ResidenceController < Officing::BaseController
|
||||
|
||||
before_action :load_officer_assignment
|
||||
before_action :validate_officer_assignment, only: :create
|
||||
before_action :verify_officer_assignment
|
||||
before_action :verify_booth
|
||||
|
||||
def new
|
||||
@residence = Officing::Residence.new
|
||||
@@ -22,16 +23,4 @@ class Officing::ResidenceController < Officing::BaseController
|
||||
params.require(:residence).permit(:document_number, :document_type, :year_of_birth)
|
||||
end
|
||||
|
||||
def load_officer_assignment
|
||||
@officer_assignments = current_user.poll_officer.
|
||||
officer_assignments.
|
||||
voting_days.
|
||||
where(date: Date.current)
|
||||
end
|
||||
|
||||
def validate_officer_assignment
|
||||
if @officer_assignments.blank?
|
||||
redirect_to officing_root_path, notice: t("officing.residence.flash.not_allowed")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ class Officing::ResultsController < Officing::BaseController
|
||||
before_action :load_officer_assignment, only: :create
|
||||
before_action :check_officer_assignment, only: :create
|
||||
before_action :build_results, only: :create
|
||||
before_action :verify_booth
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
class Officing::VotersController < Officing::BaseController
|
||||
respond_to :html, :js
|
||||
|
||||
before_action :load_officer_assignment
|
||||
before_action :verify_officer_assignment
|
||||
before_action :verify_booth
|
||||
|
||||
def new
|
||||
@user = User.find(params[:id])
|
||||
booths = current_user.poll_officer.shifts.current.vote_collection.pluck(:booth_id).uniq
|
||||
@@ -15,7 +19,9 @@ class Officing::VotersController < Officing::BaseController
|
||||
user: @user,
|
||||
poll: @poll,
|
||||
origin: "booth",
|
||||
officer: current_user.poll_officer)
|
||||
officer: current_user.poll_officer,
|
||||
booth_assignment: Poll::BoothAssignment.where(poll: @poll, booth: current_booth).first,
|
||||
officer_assignment: officer_assignment(@poll))
|
||||
@voter.save!
|
||||
end
|
||||
|
||||
@@ -25,4 +31,13 @@ class Officing::VotersController < Officing::BaseController
|
||||
params.require(:voter).permit(:poll_id, :user_id)
|
||||
end
|
||||
|
||||
def officer_assignment(poll)
|
||||
Poll::OfficerAssignment.by_officer(current_user.poll_officer)
|
||||
.by_poll(poll)
|
||||
.by_booth(current_booth)
|
||||
.by_date(Date.current)
|
||||
.where(final: false)
|
||||
.first
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -3,7 +3,9 @@ class Users::SessionsController < Devise::SessionsController
|
||||
private
|
||||
|
||||
def after_sign_in_path_for(resource)
|
||||
if !verifying_via_email? && resource.show_welcome_screen?
|
||||
if current_user.poll_officer?
|
||||
new_officing_booth_path
|
||||
elsif !verifying_via_email? && resource.show_welcome_screen?
|
||||
welcome_path
|
||||
else
|
||||
super
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
module AdminBudgetInvestmentsHelper
|
||||
|
||||
def advanced_menu_visibility
|
||||
(params[:advanced_filters].empty? && params["min_total_supports"].blank?) ? "hide" : ""
|
||||
if params[:advanced_filters].empty? &&
|
||||
params["min_total_supports"].blank? &&
|
||||
params["max_total_supports"].blank?
|
||||
"hide"
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def init_advanced_menu
|
||||
|
||||
@@ -5,11 +5,15 @@ module OfficersHelper
|
||||
end
|
||||
|
||||
def vote_collection_shift?
|
||||
current_user.poll_officer.officer_assignments.where(date: Time.current.to_date).any?
|
||||
current_user.poll_officer.officer_assignments.voting_days.where(date: Time.current.to_date).any?
|
||||
end
|
||||
|
||||
def final_recount_shift?
|
||||
current_user.poll_officer.officer_assignments.final.where(date: Time.current.to_date).any?
|
||||
end
|
||||
|
||||
def no_shifts?
|
||||
current_user.poll_officer.officer_assignments.where(date: Time.current.to_date).blank?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -117,7 +117,9 @@ class Budget
|
||||
results = Investment.by_budget(budget)
|
||||
|
||||
results = results.where("cached_votes_up + physical_votes >= ?",
|
||||
params[:min_total_supports]) if params[:min_total_supports].present?
|
||||
params[:min_total_supports]) if params[:min_total_supports].present?
|
||||
results = results.where("cached_votes_up + physical_votes <= ?",
|
||||
params[:max_total_supports]) if params[:max_total_supports].present?
|
||||
results = results.where(group_id: params[:group_id]) if params[:group_id].present?
|
||||
results = results.by_tag(params[:tag_name]) if params[:tag_name].present?
|
||||
results = results.by_heading(params[:heading_id]) if params[:heading_id].present?
|
||||
@@ -132,12 +134,19 @@ class Budget
|
||||
end
|
||||
|
||||
def self.advanced_filters(params, results)
|
||||
results = results.without_admin if params[:advanced_filters].include?("without_admin")
|
||||
results = results.without_valuator if params[:advanced_filters].include?("without_valuator")
|
||||
results = results.under_valuation if params[:advanced_filters].include?("under_valuation")
|
||||
results = results.valuation_finished if params[:advanced_filters].include?("valuation_finished")
|
||||
results = results.winners if params[:advanced_filters].include?("winners")
|
||||
|
||||
ids = []
|
||||
ids += results.valuation_finished_feasible.pluck(:id) if params[:advanced_filters].include?("feasible")
|
||||
ids += results.where(selected: true).pluck(:id) if params[:advanced_filters].include?("selected")
|
||||
ids += results.undecided.pluck(:id) if params[:advanced_filters].include?("undecided")
|
||||
ids += results.unfeasible.pluck(:id) if params[:advanced_filters].include?("unfeasible")
|
||||
results.where("budget_investments.id IN (?)", ids)
|
||||
results = results.where("budget_investments.id IN (?)", ids) if ids.any?
|
||||
results
|
||||
end
|
||||
|
||||
def self.order_filter(params)
|
||||
|
||||
@@ -58,6 +58,10 @@ class Budget::Investment::Exporter
|
||||
|
||||
def price(investment)
|
||||
price_string = "admin.budget_investments.index.feasibility.#{investment.feasibility}"
|
||||
I18n.t(price_string, price: investment.formatted_price)
|
||||
if investment.feasible?
|
||||
"#{I18n.t(price_string)} (#{investment.formatted_price})"
|
||||
else
|
||||
I18n.t(price_string)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -23,5 +23,9 @@ class Poll
|
||||
sort {|x, y| y.ends_at <=> x.ends_at}
|
||||
end
|
||||
|
||||
def todays_booths
|
||||
officer_assignments.by_date(Date.current).map(&:booth).uniq
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,11 +17,20 @@ class Poll
|
||||
scope :by_officer_and_poll, ->(officer_id, poll_id) do
|
||||
where("officer_id = ? AND poll_booth_assignments.poll_id = ?", officer_id, poll_id)
|
||||
end
|
||||
scope :by_officer, ->(officer){ where(officer_id: officer.id) }
|
||||
scope :by_poll, ->(poll){ joins(:booth_assignment).where("poll_booth_assignments.poll_id" => poll.id) }
|
||||
scope :by_booth, ->(booth){ joins(:booth_assignment).where("poll_booth_assignments.booth_id" => booth.id) }
|
||||
scope :by_date, ->(date){ where(date: date) }
|
||||
|
||||
before_create :log_user_data
|
||||
|
||||
def log_user_data
|
||||
self.user_data_log = "#{officer.user_id} - #{officer.user.name_and_email}"
|
||||
end
|
||||
|
||||
def booth
|
||||
booth_assignment.booth
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,11 +12,13 @@ class Poll
|
||||
|
||||
validates :poll_id, presence: true
|
||||
validates :user_id, presence: true
|
||||
validates :booth_assignment_id, presence: true, if: ->(voter) { voter.origin == "booth" }
|
||||
validates :officer_assignment_id, presence: true, if: ->(voter) { voter.origin == "booth" }
|
||||
|
||||
validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted }
|
||||
validates :origin, inclusion: { in: VALID_ORIGINS }
|
||||
|
||||
before_validation :set_demographic_info, :set_document_info
|
||||
before_validation :set_demographic_info, :set_document_info, :set_denormalized_booth_assignment_id
|
||||
|
||||
scope :web, -> { where(origin: "web") }
|
||||
scope :booth, -> { where(origin: "booth") }
|
||||
@@ -38,6 +40,10 @@ class Poll
|
||||
|
||||
private
|
||||
|
||||
def set_denormalized_booth_assignment_id
|
||||
self.booth_assignment_id ||= officer_assignment.try(:booth_assignment_id)
|
||||
end
|
||||
|
||||
def in_census?
|
||||
census_api_response.valid?
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
admin_budget_budget_investments_path(csv_params),
|
||||
class: "float-right small clear" %>
|
||||
|
||||
<% if params[:filter] == "winners" %>
|
||||
<% if params[:advanced_filters].include?("winners") %>
|
||||
<% if display_calculate_winners_button?(@budget) %>
|
||||
<%= link_to calculate_winner_button_text(@budget),
|
||||
calculate_winners_admin_budget_path(@budget),
|
||||
@@ -36,6 +36,7 @@
|
||||
</th>
|
||||
<th><%= t("admin.budget_investments.index.list.geozone") %></th>
|
||||
<th><%= t("admin.budget_investments.index.list.feasibility") %></th>
|
||||
<th><%= t("admin.budget_investments.index.list.price") %></th>
|
||||
<th class="text-center"><%= t("admin.budget_investments.index.list.valuation_finished") %></th>
|
||||
<th class="text-center"><%= t("admin.budget_investments.index.list.visible_to_valuators") %></th>
|
||||
<th class="text-center"><%= t("admin.budget_investments.index.list.selected") %></th>
|
||||
|
||||
@@ -11,14 +11,22 @@
|
||||
<div id="advanced_filters" class="<%= advanced_menu_visibility %>" data-toggler=".hide">
|
||||
<div class="small-12 column">
|
||||
<div class="advanced-filters-content">
|
||||
<% ["feasible", "selected", "undecided", "unfeasible"].each do |option| %>
|
||||
<% %w[feasible selected undecided unfeasible without_admin without_valuator under_valuation
|
||||
valuation_finished winners].each do |filter| %>
|
||||
<div class="filter">
|
||||
<%= check_box_tag "advanced_filters[]", option, params[:advanced_filters].index(option), id: "advanced_filters_#{option}" %>
|
||||
<%= t("admin.budget_investments.index.filters.#{option}") %>
|
||||
<%= check_box_tag "advanced_filters[]", filter, params[:advanced_filters].index(filter), id: "advanced_filters_#{filter}" %>
|
||||
<%= label_tag "advanced_filters[#{filter}]", t("admin.budget_investments.index.filters.#{filter}") %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="filter">
|
||||
<%= text_field_tag :min_total_supports, params["min_total_supports"], placeholder: t("admin.budget_investments.index.filters.min_total_supports") %>
|
||||
<div>
|
||||
<div class="filter">
|
||||
<%= label_tag :min_total_supports, t("admin.budget_investments.index.filters.min_total_supports") %>
|
||||
<%= text_field_tag :min_total_supports, params["min_total_supports"] %>
|
||||
</div>
|
||||
<div class="filter">
|
||||
<%= label_tag :max_total_supports, t("admin.budget_investments.index.filters.max_total_supports") %>
|
||||
<%= text_field_tag :max_total_supports, params["max_total_supports"] %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -31,8 +31,10 @@
|
||||
<%= investment.heading.name %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}",
|
||||
price: investment.formatted_price) %>
|
||||
<%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}") %>
|
||||
</td>
|
||||
<td class="small">
|
||||
<%= investment.formatted_price %>
|
||||
</td>
|
||||
<td class="small text-center">
|
||||
<%= investment.valuation_finished? ? t("shared.yes"): t("shared.no") %>
|
||||
@@ -54,6 +56,7 @@
|
||||
filter: params[:filter],
|
||||
sort_by: params[:sort_by],
|
||||
min_total_supports: params[:min_total_supports],
|
||||
max_total_supports: params[:max_total_supports],
|
||||
advanced_filters: params[:advanced_filters],
|
||||
page: params[:page]),
|
||||
method: :patch,
|
||||
@@ -67,6 +70,7 @@
|
||||
filter: params[:filter],
|
||||
sort_by: params[:sort_by],
|
||||
min_total_supports: params[:min_total_supports],
|
||||
max_total_supports: params[:max_total_supports],
|
||||
advanced_filters: params[:advanced_filters],
|
||||
page: params[:page]),
|
||||
method: :patch,
|
||||
|
||||
@@ -43,14 +43,14 @@
|
||||
<%= link_to booth_assignment.booth.name, admin_poll_booth_assignment_path(@poll, booth_assignment, anchor: "tab-recounts") %>
|
||||
</strong>
|
||||
</td>
|
||||
<td class="text-center <%= "count-error" if total_recounts.to_i != system_count %>">
|
||||
<td class="text-center <%= "count-error" if total_recounts.to_i != system_count %>" id="<%= dom_id(booth_assignment) %>_recount">
|
||||
<% if total_recounts.present? %>
|
||||
<strong><%= total_recounts %></strong>
|
||||
<% else %>
|
||||
<span>-</span>
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<td class="text-center" id="<%= dom_id(booth_assignment) %>_system">
|
||||
<% if system_count.present? %>
|
||||
<strong><%= system_count %></strong>
|
||||
<% else %>
|
||||
|
||||
@@ -9,11 +9,10 @@
|
||||
<%= t("budgets.ballots.show.voted_html",
|
||||
count: @ballot.investments.count) %>
|
||||
</h2>
|
||||
<p class="confirmed">
|
||||
<%= t("budgets.ballots.show.voted_info_html") %>
|
||||
<p>
|
||||
<small>
|
||||
<%= t("budgets.ballots.show.voted_info_html") %>
|
||||
</small>
|
||||
</p>
|
||||
<p><%= t("budgets.ballots.show.voted_info_2") %></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -71,4 +71,8 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<%= link_to t("budgets.investments.header.check_ballot"),
|
||||
budget_ballot_path(@budget),
|
||||
class: "button hollow expanded" %>
|
||||
<% end %>
|
||||
|
||||
5
app/views/layouts/_officing_booth.html.erb
Normal file
5
app/views/layouts/_officing_booth.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<% if current_user.poll_officer? %>
|
||||
<div id="officing-booth" class="callout info">
|
||||
<%= t("admin.officing_booth.title", booth: try(:current_booth).try(:location)) %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
<div class="admin-content small-12 medium-9 column" data-equalizer-watch>
|
||||
<%= render "layouts/flash" %>
|
||||
<%= render "layouts/officing_booth" %>
|
||||
<%= yield %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
25
app/views/officing/booth/new.html.erb
Normal file
25
app/views/officing/booth/new.html.erb
Normal file
@@ -0,0 +1,25 @@
|
||||
<div class="row margin-top">
|
||||
<div class="small-12 medium-6 column small-centered">
|
||||
<div class="panel margin-top">
|
||||
<h1 class="text-center">
|
||||
<%= t("officing.booth.new.title") %>
|
||||
</h1>
|
||||
<%= form_for Poll::Booth.new,
|
||||
as: :booth,
|
||||
url: officing_booth_path,
|
||||
method: :post do |f| %>
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<%= f.select :id,
|
||||
@booths.collect { |booth| [booth.location, booth.id] },
|
||||
selected: @booths.first,
|
||||
label: false,
|
||||
tabindex: "1" %>
|
||||
|
||||
<%= f.submit(t("devise_views.sessions.new.submit"), class: "button expanded") %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<p><%= t("officing.dashboard.index.info") %></p>
|
||||
|
||||
<% unless final_recount_shift? && vote_collection_shift? %>
|
||||
<% if no_shifts? %>
|
||||
<div class="callout warning">
|
||||
<%= t("officing.dashboard.index.no_shifts") %>
|
||||
</div>
|
||||
|
||||
@@ -1,32 +1,25 @@
|
||||
<h2><%= t("officing.residence.new.title") %></h2>
|
||||
|
||||
<% if @officer_assignments.present? %>
|
||||
<div class="row verification account">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= form_for @residence, as: "residence", url: officing_residence_path do |f| %>
|
||||
<%= render "errors" %>
|
||||
<div class="row verification account">
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= form_for @residence, as: "residence", url: officing_residence_path do |f| %>
|
||||
<%= render "errors" %>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<%= f.select :document_type, document_types, prompt: "" %>
|
||||
<div class="small-12 medium-6">
|
||||
<%= f.select :document_type, document_types, prompt: "" %>
|
||||
|
||||
|
||||
<%= f.text_field :document_number,
|
||||
<%= f.text_field :document_number,
|
||||
placeholder: t("officing.residence.new.document_number"),
|
||||
autocomplete: "off" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="date-of-birth small-12 medium-6">
|
||||
<%= f.text_field :year_of_birth, type: "number", autocomplete: "off" %>
|
||||
</div>
|
||||
<div class="date-of-birth small-12 medium-6">
|
||||
<%= f.text_field :year_of_birth, type: "number", autocomplete: "off" %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<input type="submit" value="<%= t("officing.residence.new.submit") %>" class="button expanded">
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="small-12 medium-6">
|
||||
<input type="submit" value="<%= t("officing.residence.new.submit") %>" class="button expanded">
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="callout primary">
|
||||
<%= t("officing.residence.new.no_assignments") %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
$("#<%= dom_id(@poll) %> #actions").html("<%= j render("voted") %>");
|
||||
$("#<%= dom_id(@poll) %> #can_vote_callout").hide();
|
||||
$("#not_voted").hide();
|
||||
$(".js-vote-collection").removeClass("is-hidden");
|
||||
|
||||
@@ -28,4 +28,8 @@
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<%= link_to t("officing.voters.new.not_to_vote"), namespaced_root_path, class: "button" %>
|
||||
<% if Poll.votable_by(@user).any? %>
|
||||
<div id="not_voted">
|
||||
<%= link_to t("officing.voters.new.not_to_vote"), namespaced_root_path, class: "button" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -14,6 +14,8 @@ en:
|
||||
edit: Edit
|
||||
configure: Configure
|
||||
delete: Delete
|
||||
officing_booth:
|
||||
title: "You are officing the booth located at %{booth}. If this is not correct, do not continue and call the help phone number. Thank you."
|
||||
banners:
|
||||
index:
|
||||
title: Banners
|
||||
@@ -191,6 +193,7 @@ en:
|
||||
undecided: Undecided
|
||||
unfeasible: Unfeasible
|
||||
min_total_supports: Minimum supports
|
||||
max_total_supports: Maximum supports
|
||||
winners: Winners
|
||||
one_filter_html: "Current applied filters: <b><em>%{filter}</em></b>"
|
||||
two_filters_html: "Current applied filters: <b><em>%{filter}, %{advanced_filters}</em></b>"
|
||||
@@ -204,7 +207,7 @@ en:
|
||||
no_valuators_assigned: No valuators assigned
|
||||
no_valuation_groups: No valuation groups assigned
|
||||
feasibility:
|
||||
feasible: "Feasible (%{price})"
|
||||
feasible: "Feasible"
|
||||
unfeasible: "Unfeasible"
|
||||
undecided: "Undecided"
|
||||
selected: "Selected"
|
||||
@@ -223,6 +226,7 @@ en:
|
||||
visible_to_valuators: Show to valuators
|
||||
author_username: Author username
|
||||
incompatible: Incompatible
|
||||
price: Price
|
||||
cannot_calculate_winners: The budget has to stay on phase "Balloting projects", "Reviewing Ballots" or "Finished budget" in order to calculate winners projects
|
||||
see_results: "See results"
|
||||
show:
|
||||
|
||||
@@ -10,7 +10,8 @@ en:
|
||||
voted_html:
|
||||
one: "You have voted <span>one</span> investment."
|
||||
other: "You have voted <span>%{count}</span> investments."
|
||||
voted_info_html: "You can change your vote at any time until the close of this phase.<br> No need to spend all the money available."
|
||||
voted_info_html: "Your ballot is confirmed!"
|
||||
voted_info_2: "But you can change your vote at any time until this phase is closed."
|
||||
zero: You have not voted any investment project.
|
||||
reasons_for_not_balloting:
|
||||
not_logged_in: You must %{signin} or %{signup} to continue.
|
||||
@@ -90,7 +91,7 @@ en:
|
||||
voted_info_link: change your vote
|
||||
different_heading_assigned_html: "You have active votes in another heading: %{heading_link}"
|
||||
change_ballot: "If your change your mind you can remove your votes in %{check_ballot} and start again."
|
||||
check_ballot_link: "check my ballot"
|
||||
check_ballot_link: "check and confirm my ballot"
|
||||
zero: You have not voted any investment project in this group.
|
||||
verified_only: "To create a new budget investment %{verify}."
|
||||
verify_account: "verify your account"
|
||||
@@ -142,10 +143,10 @@ en:
|
||||
zero: No supports
|
||||
give_support: Support
|
||||
header:
|
||||
check_ballot: Check my ballot
|
||||
check_ballot: Check and confirm my ballot
|
||||
different_heading_assigned_html: "You have active votes in another heading: %{heading_link}"
|
||||
change_ballot: "If your change your mind you can remove your votes in %{check_ballot} and start again."
|
||||
check_ballot_link: "check my ballot"
|
||||
check_ballot_link: "check and confirm my ballot"
|
||||
price: "This heading has a budget of"
|
||||
progress_bar:
|
||||
assigned: "You have assigned: "
|
||||
|
||||
@@ -16,6 +16,9 @@ en:
|
||||
no_polls: You are not officing final recounts in any active poll
|
||||
select_poll: Select poll
|
||||
add_results: Add results
|
||||
booth:
|
||||
new:
|
||||
title: "Choose your booth"
|
||||
results:
|
||||
flash:
|
||||
create: "Results saved"
|
||||
@@ -51,7 +54,6 @@ en:
|
||||
submit: Validate document
|
||||
error_verifying_census: "The Census was unable to verify this document."
|
||||
form_errors: prevented the verification of this document
|
||||
no_assignments: "You don't have officing shifts today"
|
||||
voters:
|
||||
new:
|
||||
title: Polls
|
||||
|
||||
@@ -14,6 +14,8 @@ es:
|
||||
edit: Editar
|
||||
configure: Configurar
|
||||
delete: Borrar
|
||||
officing_booth:
|
||||
title: "Estás ahora mismo en la mesa ubicada en %{booth}. Si esto no es correcto no sigas adelante y llama al teléfono de incidencias. Gracias."
|
||||
banners:
|
||||
index:
|
||||
title: Banners
|
||||
@@ -191,6 +193,7 @@ es:
|
||||
undecided: Sin decidir
|
||||
unfeasible: Inviables
|
||||
min_total_supports: Apoyos mínimos
|
||||
max_total_supports: Apoyos máximos
|
||||
winners: Ganadores
|
||||
one_filter_html: "Filtros en uso: <b><em>%{filter}</em></b>"
|
||||
two_filters_html: "Filtros en uso: <b><em>%{filter}, %{advanced_filters}</em></b>"
|
||||
@@ -204,7 +207,7 @@ es:
|
||||
no_valuators_assigned: Sin evaluador
|
||||
no_valuation_groups: Sin grupos evaluadores
|
||||
feasibility:
|
||||
feasible: "Viable (%{price})"
|
||||
feasible: "Viable"
|
||||
unfeasible: "Inviable"
|
||||
undecided: "Sin decidir"
|
||||
selected: "Seleccionado"
|
||||
@@ -223,6 +226,7 @@ es:
|
||||
visible_to_valuators: Mostrar a evaluadores
|
||||
author_username: Usuario autor
|
||||
incompatible: Incompatible
|
||||
price: Precio
|
||||
cannot_calculate_winners: El presupuesto debe estar en las fases "Votación final", "Votación finalizada" o "Resultados" para poder calcular las propuestas ganadoras
|
||||
see_results: "Ver resultados"
|
||||
show:
|
||||
|
||||
@@ -10,7 +10,8 @@ es:
|
||||
voted_html:
|
||||
one: "Has votado <span>un</span> proyecto."
|
||||
other: "Has votado <span>%{count}</span> proyectos."
|
||||
voted_info_html: "Puedes cambiar tus votos en cualquier momento hasta el cierre de esta fase.<br> No hace falta que gastes todo el dinero disponible."
|
||||
voted_info_html: "¡Tus votos están confirmados!"
|
||||
voted_info_2: "Pero puedes cambiarlos en cualquier momento hasta el cierre de esta fase."
|
||||
zero: Todavía no has votado ningún proyecto de gasto.
|
||||
reasons_for_not_balloting:
|
||||
not_logged_in: Necesitas %{signin} o %{signup} para continuar.
|
||||
@@ -90,7 +91,7 @@ es:
|
||||
voted_info_link: cambiar tus votos
|
||||
different_heading_assigned_html: "Ya apoyaste proyectos de otra sección del presupuesto: %{heading_link}"
|
||||
change_ballot: "Si cambias de opinión puedes borrar tus votos en %{check_ballot} y volver a empezar."
|
||||
check_ballot_link: "revisar mis votos"
|
||||
check_ballot_link: "revisar y confirmar mis votos"
|
||||
zero: Todavía no has votado ningún proyecto de gasto en este ámbito del presupuesto.
|
||||
verified_only: "Para crear un nuevo proyecto de gasto %{verify}."
|
||||
verify_account: "verifica tu cuenta"
|
||||
@@ -142,10 +143,10 @@ es:
|
||||
other: "%{count} apoyos"
|
||||
give_support: Apoyar
|
||||
header:
|
||||
check_ballot: Revisar mis votos
|
||||
check_ballot: Revisar y confirmar mis votos
|
||||
different_heading_assigned_html: "Ya apoyaste proyectos de otra sección del presupuesto: %{heading_link}"
|
||||
change_ballot: "Si cambias de opinión puedes borrar tus votos en %{check_ballot} y volver a empezar."
|
||||
check_ballot_link: "revisar mis votos"
|
||||
check_ballot_link: "revisar y confirmar mis votos"
|
||||
price: "Esta partida tiene un presupuesto de"
|
||||
progress_bar:
|
||||
assigned: "Has asignado: "
|
||||
|
||||
@@ -16,6 +16,9 @@ es:
|
||||
no_polls: No tienes permiso para recuento final en ninguna votación reciente
|
||||
select_poll: Selecciona votación
|
||||
add_results: Añadir resultados
|
||||
booth:
|
||||
new:
|
||||
title: "Escoge tu urna"
|
||||
results:
|
||||
flash:
|
||||
create: "Datos guardados"
|
||||
@@ -51,7 +54,6 @@ es:
|
||||
submit: Validar documento
|
||||
error_verifying_census: "El Padrón no pudo verificar este documento."
|
||||
form_errors: evitaron verificar este documento
|
||||
no_assignments: "Hoy no tienes turno de presidente de mesa"
|
||||
voters:
|
||||
new:
|
||||
title: Votaciones
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace :officing do
|
||||
resources :results, only: [:new, :create, :index]
|
||||
end
|
||||
|
||||
resource :booth, controller: "booth", only: [:new, :create]
|
||||
resource :residence, controller: "residence", only: [:new, :create]
|
||||
resources :voters, only: [:new, :create]
|
||||
root to: "dashboard#index"
|
||||
|
||||
@@ -42,13 +42,13 @@ end
|
||||
section "Creating Poll Questions & Answers" do
|
||||
Poll.find_each do |poll|
|
||||
(1..4).to_a.sample.times do
|
||||
title = Faker::Lorem.sentence(3).truncate(60) + "?"
|
||||
question_title = Faker::Lorem.sentence(3).truncate(60) + "?"
|
||||
question = Poll::Question.new(author: User.all.sample,
|
||||
title: title,
|
||||
title: question_title,
|
||||
poll: poll)
|
||||
I18n.available_locales.map do |locale|
|
||||
Globalize.with_locale(locale) do
|
||||
question.title = "#{title} (#{locale})"
|
||||
question.title = "#{question_title} (#{locale})"
|
||||
end
|
||||
end
|
||||
question.save!
|
||||
@@ -115,12 +115,16 @@ end
|
||||
section "Creating Poll Voters" do
|
||||
|
||||
def vote_poll_on_booth(user, poll)
|
||||
officer = Poll::Officer.all.sample
|
||||
|
||||
Poll::Voter.create!(document_type: user.document_type,
|
||||
document_number: user.document_number,
|
||||
user: user,
|
||||
poll: poll,
|
||||
origin: "booth",
|
||||
officer: Poll::Officer.all.sample)
|
||||
officer: officer,
|
||||
officer_assignment: officer.officer_assignments.sample,
|
||||
booth_assignment: poll.booth_assignments.sample)
|
||||
end
|
||||
|
||||
def vote_poll_on_web(user, poll)
|
||||
@@ -143,11 +147,11 @@ section "Creating Poll Voters" do
|
||||
end
|
||||
|
||||
(Poll.expired + Poll.current + Poll.recounting).uniq.each do |poll|
|
||||
level_two_verified_users = User.level_two_verified
|
||||
verified_users = User.level_two_or_three_verified
|
||||
if poll.geozone_restricted?
|
||||
level_two_verified_users = level_two_verified_users.where(geozone_id: poll.geozone_ids)
|
||||
verified_users = verified_users.where(geozone_id: poll.geozone_ids)
|
||||
end
|
||||
user_groups = level_two_verified_users.in_groups(2)
|
||||
user_groups = verified_users.in_groups(2)
|
||||
user_groups.first.each { |user| vote_poll_on_booth(user, poll) }
|
||||
user_groups.second.compact.each { |user| vote_poll_on_web(user, poll) }
|
||||
end
|
||||
@@ -159,13 +163,23 @@ section "Creating Poll Recounts" do
|
||||
officer_assignment = poll.officer_assignments.first
|
||||
author = Poll::Officer.first.user
|
||||
|
||||
total_amount = white_amount = null_amount = 0
|
||||
|
||||
booth_assignment.voters.count.times do
|
||||
case rand
|
||||
when 0...0.1 then null_amount += 1
|
||||
when 0.1...0.2 then white_amount += 1
|
||||
else total_amount += 1
|
||||
end
|
||||
end
|
||||
|
||||
Poll::Recount.create!(officer_assignment: officer_assignment,
|
||||
booth_assignment: booth_assignment,
|
||||
author: author,
|
||||
date: poll.ends_at,
|
||||
white_amount: rand(0..10),
|
||||
null_amount: rand(0..10),
|
||||
total_amount: rand(100..9999),
|
||||
white_amount: white_amount,
|
||||
null_amount: null_amount,
|
||||
total_amount: total_amount,
|
||||
origin: "booth")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ section "Creating Users" do
|
||||
password_confirmation: password,
|
||||
confirmed_at: Time.current,
|
||||
terms_of_service: "1",
|
||||
gender: ["Male", "Female"].sample,
|
||||
gender: %w[male female].sample,
|
||||
date_of_birth: rand((Time.current - 80.years)..(Time.current - 16.years)),
|
||||
public_activity: (rand(1..100) > 30)
|
||||
)
|
||||
|
||||
@@ -150,13 +150,17 @@ FactoryBot.define do
|
||||
valuation_finished true
|
||||
end
|
||||
|
||||
trait :hidden do
|
||||
hidden_at { Time.current }
|
||||
end
|
||||
trait :hidden do
|
||||
hidden_at { Time.current }
|
||||
end
|
||||
|
||||
trait :with_ignored_flag do
|
||||
ignored_flag_at { Time.current }
|
||||
end
|
||||
trait :with_ignored_flag do
|
||||
ignored_flag_at { Time.current }
|
||||
end
|
||||
|
||||
trait :with_administrator do
|
||||
administrator
|
||||
end
|
||||
|
||||
trait :flagged do
|
||||
after :create do |investment|
|
||||
|
||||
@@ -251,12 +251,161 @@ feature "Admin budget investments" do
|
||||
expect(page).not_to have_link("Build a hospital")
|
||||
end
|
||||
|
||||
scenario "Filtering by without assigned admin", :js do
|
||||
create(:budget_investment,
|
||||
title: "Investment without admin",
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
:with_administrator,
|
||||
title: "Investment with admin",
|
||||
budget: budget)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget)
|
||||
expect(page).to have_link("Investment without admin")
|
||||
expect(page).to have_link("Investment with admin")
|
||||
|
||||
click_link "Advanced filters"
|
||||
check("Without assigned admin")
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There is 1 investment")
|
||||
expect(page).to have_link("Investment without admin")
|
||||
expect(page).not_to have_link("Investment with admin")
|
||||
|
||||
uncheck("Without assigned admin")
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There are 2 investments")
|
||||
expect(page).to have_link("Investment without admin")
|
||||
expect(page).to have_link("Investment with admin")
|
||||
end
|
||||
|
||||
scenario "Filtering by without assigned valuator", :js do
|
||||
user = create(:user)
|
||||
valuator = create(:valuator, user: user)
|
||||
create(:budget_investment,
|
||||
title: "Investment without valuator",
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
title: "Investment with valuator",
|
||||
budget: budget,
|
||||
valuators: [valuator])
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget)
|
||||
expect(page).to have_link("Investment without valuator")
|
||||
expect(page).to have_link("Investment with valuator")
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Without assigned valuator"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There is 1 investment")
|
||||
expect(page).to have_link("Investment without valuator")
|
||||
expect(page).not_to have_link("Investment with valuator")
|
||||
|
||||
uncheck "Without assigned valuator"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There are 2 investments")
|
||||
expect(page).to have_link("Investment without valuator")
|
||||
expect(page).to have_link("Investment with valuator")
|
||||
end
|
||||
|
||||
scenario "Filtering by under valuation", :js do
|
||||
user = create(:user)
|
||||
valuator = create(:valuator, user: user)
|
||||
create(:budget_investment,
|
||||
:with_administrator,
|
||||
valuation_finished: false,
|
||||
title: "Investment without valuation",
|
||||
budget: budget,
|
||||
valuators: [valuator])
|
||||
create(:budget_investment,
|
||||
:with_administrator,
|
||||
title: "Investment with valuation",
|
||||
budget: budget)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget)
|
||||
expect(page).to have_link("Investment without valuation")
|
||||
expect(page).to have_link("Investment with valuation")
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There is 1 investment")
|
||||
expect(page).to have_link("Investment without valuation")
|
||||
expect(page).not_to have_link("Investment with valuation")
|
||||
|
||||
uncheck "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There are 2 investments")
|
||||
expect(page).to have_link("Investment without valuation")
|
||||
expect(page).to have_link("Investment with valuation")
|
||||
end
|
||||
|
||||
scenario "Filtering by valuation finished", :js do
|
||||
create(:budget_investment,
|
||||
title: "Investment valuation open",
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
:finished,
|
||||
title: "Investment valuation finished",
|
||||
budget: budget)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget)
|
||||
expect(page).to have_link("Investment valuation open")
|
||||
expect(page).to have_link("Investment valuation finished")
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Valuation finished"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There is 1 investment")
|
||||
expect(page).not_to have_link("Investment valuation open")
|
||||
expect(page).to have_link("Investment valuation finished")
|
||||
|
||||
uncheck "Valuation finished"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There are 2 investments")
|
||||
expect(page).to have_link("Investment valuation open")
|
||||
expect(page).to have_link("Investment valuation finished")
|
||||
end
|
||||
|
||||
scenario "Filtering by winners", :js do
|
||||
create(:budget_investment,
|
||||
:winner,
|
||||
valuation_finished: true,
|
||||
title: "Investment winner",
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
title: "Investment without winner",
|
||||
budget: budget)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget)
|
||||
expect(page).to have_link("Investment winner")
|
||||
expect(page).to have_link("Investment without winner")
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Winners"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There is 1 investment")
|
||||
expect(page).to have_link("Investment winner")
|
||||
expect(page).not_to have_link("Investment without winner")
|
||||
|
||||
uncheck "Winners"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There are 2 investments")
|
||||
expect(page).to have_link("Investment winner")
|
||||
expect(page).to have_link("Investment without winner")
|
||||
end
|
||||
|
||||
scenario "Current filter is properly highlighted" do
|
||||
filters_links = { "all" => "All",
|
||||
"without_admin" => "Without assigned admin",
|
||||
"without_valuator" => "Without assigned valuator",
|
||||
"under_valuation" => "Under valuation",
|
||||
"valuation_finished" => "Valuation finished" }
|
||||
filters_links = { "all" => "All" }
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id)
|
||||
|
||||
@@ -288,13 +437,15 @@ feature "Admin budget investments" do
|
||||
expect(page).to have_content("Evaluating...")
|
||||
expect(page).to have_content("With group")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id, filter: "without_admin")
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id,
|
||||
advanced_filters: ["without_admin"])
|
||||
|
||||
expect(page).to have_content("Evaluating...")
|
||||
expect(page).to have_content("With group")
|
||||
expect(page).not_to have_content("Assigned idea")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id, filter: "without_valuator")
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id,
|
||||
advanced_filters: ["without_valuator"])
|
||||
|
||||
expect(page).to have_content("Assigned idea")
|
||||
expect(page).not_to have_content("Evaluating...")
|
||||
@@ -309,17 +460,20 @@ feature "Admin budget investments" do
|
||||
valuating.valuators.push(create(:valuator))
|
||||
valuated.valuators.push(create(:valuator))
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id, filter: "under_valuation")
|
||||
query_params = {budget_id: budget.id, advanced_filters: ["under_valuation"]}
|
||||
|
||||
visit admin_budget_budget_investments_path(query_params)
|
||||
|
||||
expect(page).to have_content("Ongoing valuation")
|
||||
expect(page).not_to have_content("Old idea")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id, filter: "valuation_finished")
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id,
|
||||
advanced_filters: ["valuation_finished"])
|
||||
|
||||
expect(page).not_to have_content("Ongoing valuation")
|
||||
expect(page).to have_content("Old idea")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id, filter: "all")
|
||||
visit admin_budget_budget_investments_path(budget_id: budget.id, advanced_filters: ["filter"])
|
||||
expect(page).to have_content("Ongoing valuation")
|
||||
expect(page).to have_content("Old idea")
|
||||
end
|
||||
@@ -380,7 +534,10 @@ feature "Admin budget investments" do
|
||||
budget.update(phase: "reviewing_ballots")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
click_link "Winners"
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Winners"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_link "Calculate Winner Investments"
|
||||
|
||||
@@ -391,7 +548,9 @@ feature "Admin budget investments" do
|
||||
budget.update(phase: "accepting")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
click_link "Winners"
|
||||
|
||||
check "Winners"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).not_to have_link "Calculate Winner Investments"
|
||||
expect(page).to have_content 'The budget has to stay on phase "Balloting projects", '\
|
||||
@@ -439,6 +598,42 @@ feature "Admin budget investments" do
|
||||
expect(page).not_to have_link("Road 100 supports")
|
||||
end
|
||||
|
||||
scenario "Filtering by maximum number of votes", :js do
|
||||
group_1 = create(:budget_group, budget: budget)
|
||||
group_2 = create(:budget_group, budget: budget)
|
||||
parks = create(:budget_heading, group: group_1)
|
||||
roads = create(:budget_heading, group: group_2)
|
||||
streets = create(:budget_heading, group: group_2)
|
||||
|
||||
create(:budget_investment, heading: parks, cached_votes_up: 40, title: "Park 40 supports")
|
||||
create(:budget_investment, heading: parks, cached_votes_up: 99, title: "Park 99 supports")
|
||||
create(:budget_investment, heading: roads, cached_votes_up: 100, title: "Road 100 supports")
|
||||
create(:budget_investment, heading: roads, cached_votes_up: 199, title: "Road 199 supports")
|
||||
create(:budget_investment, heading: streets, cached_votes_up: 200, title: "St. 200 supports")
|
||||
create(:budget_investment, heading: streets, cached_votes_up: 300, title: "St. 300 supports")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
|
||||
expect(page).to have_link("Park 40 supports")
|
||||
expect(page).to have_link("Park 99 supports")
|
||||
expect(page).to have_link("Road 100 supports")
|
||||
expect(page).to have_link("Road 199 supports")
|
||||
expect(page).to have_link("St. 200 supports")
|
||||
expect(page).to have_link("St. 300 supports")
|
||||
|
||||
click_link "Advanced filters"
|
||||
fill_in "max_total_supports", with: 180
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content("There are 3 investments")
|
||||
expect(page).not_to have_link("Road 199 supports")
|
||||
expect(page).not_to have_link("St. 200 supports")
|
||||
expect(page).not_to have_link("St. 300 supports")
|
||||
expect(page).to have_link("Park 40 supports")
|
||||
expect(page).to have_link("Park 99 supports")
|
||||
expect(page).to have_link("Road 100 supports")
|
||||
end
|
||||
|
||||
scenario "Combination of checkbox with text search", :js do
|
||||
user = create(:user, username: "Admin 1")
|
||||
administrator = create(:administrator, user: user)
|
||||
@@ -494,7 +689,7 @@ feature "Admin budget investments" do
|
||||
|
||||
click_link "Advanced filters"
|
||||
|
||||
page.check("advanced_filters_feasible")
|
||||
check("Feasible")
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_css(".budget_investment", count: 2)
|
||||
@@ -549,7 +744,7 @@ feature "Admin budget investments" do
|
||||
|
||||
click_link "Advanced filters"
|
||||
|
||||
within("#advanced_filters") { check("advanced_filters_feasible") }
|
||||
within("#advanced_filters") { check("Feasible") }
|
||||
click_button("Filter")
|
||||
|
||||
expect(page).to have_css(".budget_investment", count: 2)
|
||||
@@ -1120,16 +1315,17 @@ feature "Admin budget investments" do
|
||||
scenario "Filtering by valuation and selection", :js do
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
|
||||
within("#filter-subnav") { click_link "Valuation finished" }
|
||||
click_link "Advanced filters"
|
||||
check "Valuation finished"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).not_to have_content(unfeasible_bi.title)
|
||||
expect(page).not_to have_content(feasible_bi.title)
|
||||
expect(page).to have_content(feasible_vf_bi.title)
|
||||
expect(page).to have_content(selected_bi.title)
|
||||
expect(page).to have_content(winner_bi.title)
|
||||
|
||||
click_link "Advanced filters"
|
||||
|
||||
within("#advanced_filters") { check("advanced_filters_feasible") }
|
||||
within("#advanced_filters") { check("Feasible") }
|
||||
click_button("Filter")
|
||||
|
||||
expect(page).not_to have_content(unfeasible_bi.title)
|
||||
@@ -1139,8 +1335,8 @@ feature "Admin budget investments" do
|
||||
expect(page).to have_content(winner_bi.title)
|
||||
|
||||
within("#advanced_filters") do
|
||||
check("advanced_filters_selected")
|
||||
uncheck("advanced_filters_feasible")
|
||||
check("Selected")
|
||||
uncheck("Feasible")
|
||||
end
|
||||
|
||||
click_button("Filter")
|
||||
@@ -1151,7 +1347,9 @@ feature "Admin budget investments" do
|
||||
expect(page).to have_content(selected_bi.title)
|
||||
expect(page).to have_content(winner_bi.title)
|
||||
|
||||
within("#filter-subnav") { click_link "Winners" }
|
||||
check "Winners"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).not_to have_content(unfeasible_bi.title)
|
||||
expect(page).not_to have_content(feasible_bi.title)
|
||||
expect(page).not_to have_content(feasible_vf_bi.title)
|
||||
@@ -1164,7 +1362,7 @@ feature "Admin budget investments" do
|
||||
|
||||
click_link "Advanced filters"
|
||||
|
||||
within("#advanced_filters") { check("advanced_filters_undecided") }
|
||||
within("#advanced_filters") { check("Undecided") }
|
||||
click_button("Filter")
|
||||
|
||||
expect(page).to have_content(undecided_bi.title)
|
||||
@@ -1174,7 +1372,7 @@ feature "Admin budget investments" do
|
||||
expect(page).not_to have_content(unfeasible_bi.title)
|
||||
expect(page).not_to have_content(feasible_vf_bi.title)
|
||||
|
||||
within("#advanced_filters") { check("advanced_filters_unfeasible") }
|
||||
within("#advanced_filters") { check("Unfeasible") }
|
||||
click_button("Filter")
|
||||
|
||||
expect(page).to have_content(undecided_bi.title)
|
||||
@@ -1219,7 +1417,7 @@ feature "Admin budget investments" do
|
||||
|
||||
click_link "Advanced filters"
|
||||
|
||||
within("#advanced_filters") { check("advanced_filters_selected") }
|
||||
within("#advanced_filters") { check("Selected") }
|
||||
click_button("Filter")
|
||||
|
||||
within("#budget_investment_#{feasible_vf_bi.id}") do
|
||||
@@ -1232,7 +1430,7 @@ feature "Admin budget investments" do
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
click_link "Advanced filters"
|
||||
|
||||
within("#advanced_filters") { check("advanced_filters_selected") }
|
||||
within("#advanced_filters") { check("Selected") }
|
||||
click_button("Filter")
|
||||
|
||||
expect(page).to have_content("There are 2 investments")
|
||||
@@ -1289,15 +1487,18 @@ feature "Admin budget investments" do
|
||||
investment2.update(administrator: admin)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
within("#filter-subnav") { click_link "Under valuation" }
|
||||
expect(page).not_to have_link("Under valuation")
|
||||
click_link "Advanced filters"
|
||||
check "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
within("#budget_investment_#{investment1.id}") do
|
||||
check "budget_investment_visible_to_valuators"
|
||||
end
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
within("#filter-subnav") { click_link "Under valuation" }
|
||||
click_link "Advanced filters"
|
||||
check "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
within("#budget_investment_#{investment1.id}") do
|
||||
expect(find("#budget_investment_visible_to_valuators")).to be_checked
|
||||
@@ -1335,15 +1536,20 @@ feature "Admin budget investments" do
|
||||
investment2.update(administrator: admin, visible_to_valuators: true)
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
within("#filter-subnav") { click_link "Under valuation" }
|
||||
expect(page).not_to have_link("Under valuation")
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
within("#budget_investment_#{investment1.id}") do
|
||||
uncheck "budget_investment_visible_to_valuators"
|
||||
end
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
within("#filter-subnav") { click_link "Under valuation" }
|
||||
|
||||
click_link "Advanced filters"
|
||||
check "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
within("#budget_investment_#{investment1.id}") do
|
||||
expect(find("#budget_investment_visible_to_valuators")).not_to be_checked
|
||||
@@ -1364,7 +1570,9 @@ feature "Admin budget investments" do
|
||||
|
||||
expect(page).to have_css("#budget_investment_visible_to_valuators")
|
||||
|
||||
within("#filter-subnav") { click_link "Under valuation" }
|
||||
click_link "Advanced filters"
|
||||
check "Under valuation"
|
||||
click_button "Filter"
|
||||
|
||||
within("#budget_investment_#{investment1.id}") do
|
||||
valuating_checkbox = find("#budget_investment_visible_to_valuators")
|
||||
@@ -1442,7 +1650,9 @@ feature "Admin budget investments" do
|
||||
create(:budget_investment, :finished, budget: budget, title: "Finished Investment")
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
within("#filter-subnav") { click_link "Valuation finished" }
|
||||
click_link "Advanced filters"
|
||||
check "Valuation finished"
|
||||
click_button "Filter"
|
||||
|
||||
click_link "Download current selection"
|
||||
|
||||
|
||||
@@ -281,7 +281,9 @@ feature "Admin budgets" do
|
||||
expect(page).not_to have_content "Calculate Winner Investments"
|
||||
|
||||
visit admin_budget_budget_investments_path(budget)
|
||||
click_link "Winners"
|
||||
click_link "Advanced filters"
|
||||
check "Winners"
|
||||
click_button "Filter"
|
||||
|
||||
expect(page).to have_content "Recalculate Winner Investments"
|
||||
expect(page).not_to have_content "Calculate Winner Investments"
|
||||
|
||||
@@ -2,7 +2,7 @@ require "rails_helper"
|
||||
|
||||
feature "Budget Poll Officing" do
|
||||
|
||||
scenario "Show sidebar menu if officer has shifts assigned" do
|
||||
scenario "Show sidebar menus if officer has shifts assigned" do
|
||||
poll = create(:poll)
|
||||
booth = create(:poll_booth)
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
@@ -10,13 +10,21 @@ feature "Budget Poll Officing" do
|
||||
user = create(:user)
|
||||
officer = create(:poll_officer, user: user)
|
||||
|
||||
create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection)
|
||||
|
||||
login_as user
|
||||
visit officing_root_path
|
||||
|
||||
expect(page).not_to have_content("You don't have officing shifts today")
|
||||
expect(page).to have_content("Validate document")
|
||||
expect(page).not_to have_content("Total recounts and results")
|
||||
|
||||
create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :recount_scrutiny)
|
||||
|
||||
officer_assignment = create(:poll_officer_assignment,
|
||||
booth_assignment: booth_assignment,
|
||||
officer: officer)
|
||||
|
||||
login_as user
|
||||
visit officing_root_path
|
||||
|
||||
expect(page).not_to have_content("You don't have officing shifts today")
|
||||
@@ -24,7 +32,7 @@ feature "Budget Poll Officing" do
|
||||
expect(page).to have_content("Total recounts and results")
|
||||
end
|
||||
|
||||
scenario "Do not show sidebar menu if officer has no shifts assigned" do
|
||||
scenario "Do not show sidebar menus if officer has no shifts assigned" do
|
||||
user = create(:user)
|
||||
officer = create(:poll_officer, user: user)
|
||||
|
||||
|
||||
@@ -117,6 +117,7 @@ feature "Ballots" do
|
||||
within("#sidebar") do
|
||||
expect(page).to have_content investment1.title
|
||||
expect(page).to have_content "€10,000"
|
||||
expect(page).to have_link("Check and confirm my ballot")
|
||||
end
|
||||
|
||||
add_to_ballot(investment2)
|
||||
@@ -127,6 +128,7 @@ feature "Ballots" do
|
||||
within("#sidebar") do
|
||||
expect(page).to have_content investment2.title
|
||||
expect(page).to have_content "€20,000"
|
||||
expect(page).to have_link("Check and confirm my ballot")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -146,6 +148,7 @@ feature "Ballots" do
|
||||
within("#sidebar") do
|
||||
expect(page).to have_content investment.title
|
||||
expect(page).to have_content "€10,000"
|
||||
expect(page).to have_link("Check and confirm my ballot")
|
||||
end
|
||||
|
||||
within("#budget_investment_#{investment.id}") do
|
||||
@@ -158,6 +161,7 @@ feature "Ballots" do
|
||||
within("#sidebar") do
|
||||
expect(page).not_to have_content investment.title
|
||||
expect(page).not_to have_content "€10,000"
|
||||
expect(page).to have_link("Check and confirm my ballot")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -454,7 +458,9 @@ feature "Ballots" do
|
||||
visit budget_investments_path(budget, heading_id: new_york.id)
|
||||
add_to_ballot(investment)
|
||||
|
||||
click_link "Check my ballot"
|
||||
within(".budget-heading") do
|
||||
click_link "Check and confirm my ballot"
|
||||
end
|
||||
|
||||
expect(page).to have_content("You have voted one investment")
|
||||
|
||||
|
||||
@@ -583,43 +583,46 @@ feature "Budget Investments" do
|
||||
|
||||
context "Orders" do
|
||||
before { budget.update(phase: "selecting") }
|
||||
let(:per_page) { Budgets::InvestmentsController::PER_PAGE }
|
||||
|
||||
scenario "Default order is random" do
|
||||
per_page = Kaminari.config.default_per_page
|
||||
(per_page + 100).times { create(:budget_investment) }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
order = all(".budget-investment h3").collect {|i| i.text }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
new_order = eq(all(".budget-investment h3").collect {|i| i.text })
|
||||
|
||||
expect(order).not_to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Random order after another order" do
|
||||
per_page = Kaminari.config.default_per_page
|
||||
(per_page + 2).times { create(:budget_investment) }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
click_link "highest rated"
|
||||
click_link "random"
|
||||
|
||||
order = all(".budget-investment h3").collect {|i| i.text }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
new_order = eq(all(".budget-investment h3").collect {|i| i.text })
|
||||
|
||||
expect(order).not_to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Random order maintained with pagination" do
|
||||
per_page = Kaminari.config.default_per_page
|
||||
(per_page + 2).times { create(:budget_investment, heading: heading) }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
|
||||
order = all(".budget-investment h3").collect {|i| i.text }
|
||||
within(".submenu .is-active") { expect(page).to have_content "random" }
|
||||
order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).not_to be_empty
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
new_order = all(".budget-investment h3").collect { |i| i.text }
|
||||
|
||||
expect(order).to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Random order after another order" do
|
||||
(per_page + 2).times { create(:budget_investment, heading: heading) }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).not_to be_empty
|
||||
|
||||
click_link "highest rated"
|
||||
click_link "random"
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
new_order = all(".budget-investment h3").collect { |i| i.text }
|
||||
|
||||
expect(order).to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Random order maintained with pagination" do
|
||||
(per_page + 2).times { create(:budget_investment, heading: heading) }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
|
||||
order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).not_to be_empty
|
||||
|
||||
click_link "Next"
|
||||
expect(page).to have_content "You're on page 2"
|
||||
@@ -627,27 +630,27 @@ feature "Budget Investments" do
|
||||
click_link "Previous"
|
||||
expect(page).to have_content "You're on page 1"
|
||||
|
||||
new_order = all(".budget-investment h3").collect {|i| i.text }
|
||||
new_order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Random order maintained when going back from show" do
|
||||
10.times { |i| create(:budget_investment, heading: heading) }
|
||||
per_page.times { |i| create(:budget_investment, heading: heading) }
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
|
||||
order = all(".budget-investment h3").collect {|i| i.text }
|
||||
order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).not_to be_empty
|
||||
|
||||
click_link Budget::Investment.first.title
|
||||
click_link "Go back"
|
||||
|
||||
new_order = all(".budget-investment h3").collect {|i| i.text }
|
||||
new_order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Investments are not repeated with random order" do
|
||||
12.times { create(:budget_investment, heading: heading) }
|
||||
# 12 instead of per_page + 2 because in each page there are 10 (in this case), not 25
|
||||
(per_page + 2).times { create(:budget_investment, heading: heading) }
|
||||
|
||||
visit budget_investments_path(budget, order: "random")
|
||||
|
||||
@@ -661,7 +664,6 @@ feature "Budget Investments" do
|
||||
common_values = first_page_investments & second_page_investments
|
||||
|
||||
expect(common_values.length).to eq(0)
|
||||
|
||||
end
|
||||
|
||||
scenario "Proposals are ordered by confidence_score" do
|
||||
@@ -686,7 +688,7 @@ feature "Budget Investments" do
|
||||
end
|
||||
|
||||
scenario "Each user has a different and consistent random budget investment order" do
|
||||
(Kaminari.config.default_per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) }
|
||||
(per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) }
|
||||
|
||||
in_browser(:one) do
|
||||
visit budget_investments_path(budget, heading: heading)
|
||||
@@ -722,7 +724,7 @@ feature "Budget Investments" do
|
||||
end
|
||||
|
||||
scenario "Each user has a equal and consistent budget investment order when the random_seed is equal" do
|
||||
(Kaminari.config.default_per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) }
|
||||
(per_page * 1.3).to_i.times { create(:budget_investment, heading: heading) }
|
||||
|
||||
in_browser(:one) do
|
||||
visit budget_investments_path(budget, heading: heading, random_seed: "1")
|
||||
@@ -741,10 +743,10 @@ feature "Budget Investments" do
|
||||
voter = create(:user, :level_two)
|
||||
login_as(voter)
|
||||
|
||||
10.times { create(:budget_investment, heading: heading) }
|
||||
per_page.times { create(:budget_investment, heading: heading) }
|
||||
|
||||
voted_investments = []
|
||||
10.times do
|
||||
per_page.times do
|
||||
investment = create(:budget_investment, heading: heading)
|
||||
create(:vote, votable: investment, voter: voter)
|
||||
voted_investments << investment
|
||||
@@ -762,17 +764,18 @@ feature "Budget Investments" do
|
||||
end
|
||||
|
||||
scenario "Order is random if budget is finished" do
|
||||
10.times { create(:budget_investment) }
|
||||
per_page.times { create(:budget_investment, :winner, heading: heading) }
|
||||
|
||||
budget.update(phase: "finished")
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
order = all(".budget-investment h3").collect {|i| i.text }
|
||||
order = all(".budget-investment h3").collect { |i| i.text }
|
||||
expect(order).not_to be_empty
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
new_order = eq(all(".budget-investment h3").collect {|i| i.text })
|
||||
new_order = all(".budget-investment h3").collect { |i| i.text }
|
||||
|
||||
expect(order).not_to eq(new_order)
|
||||
expect(order).to eq(new_order)
|
||||
end
|
||||
|
||||
scenario "Order always is random for unfeasible and unselected investments" do
|
||||
@@ -930,10 +933,12 @@ feature "Budget Investments" do
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
|
||||
expect(page).not_to have_link("Check my ballot")
|
||||
expect(page).not_to have_link("Check and confirm my ballot")
|
||||
expect(page).not_to have_css("#progress_bar")
|
||||
|
||||
within("#sidebar") do
|
||||
expect(page).not_to have_content("My ballot")
|
||||
expect(page).not_to have_link("Check and confirm my ballot")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1564,7 +1569,8 @@ feature "Budget Investments" do
|
||||
|
||||
visit budget_ballot_path(budget)
|
||||
|
||||
expect(page).to have_content "You can change your vote at any time until the close of this phase"
|
||||
expect(page).to have_content "But you can change your vote at any time "\
|
||||
"until this phase is closed."
|
||||
|
||||
within("#budget_group_#{global_group.id}") do
|
||||
expect(page).to have_content sp1.title
|
||||
@@ -1627,10 +1633,12 @@ feature "Budget Investments" do
|
||||
|
||||
visit budget_investments_path(budget, heading_id: heading.id)
|
||||
|
||||
expect(page).to have_link("Check my ballot")
|
||||
expect(page).to have_link("Check and confirm my ballot")
|
||||
expect(page).to have_css("#progress_bar")
|
||||
|
||||
within("#sidebar") do
|
||||
expect(page).to have_content("My ballot")
|
||||
expect(page).to have_link("Check and confirm my ballot")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
87
spec/features/officing/booth_spec.rb
Normal file
87
spec/features/officing/booth_spec.rb
Normal file
@@ -0,0 +1,87 @@
|
||||
require "rails_helper"
|
||||
|
||||
feature "Booth", :with_frozen_time do
|
||||
|
||||
scenario "Officer with no booth assignments today" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
expect(page).to have_content "You don't have officing shifts today"
|
||||
end
|
||||
|
||||
scenario "Officer with booth assignments another day" do
|
||||
officer = create(:poll_officer)
|
||||
create(:poll_officer_assignment, officer: officer, date: Date.current + 1.day)
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
expect(page).to have_content "You don't have officing shifts today"
|
||||
end
|
||||
|
||||
scenario "Officer with single booth assignment today" do
|
||||
officer = create(:poll_officer)
|
||||
poll = create(:poll)
|
||||
|
||||
booth = create(:poll_booth)
|
||||
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment, date: Date.current)
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
within("#officing-booth") do
|
||||
expect(page).to have_content "You are officing the booth located at #{booth.location}."
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Officer with multiple booth assignments today" do
|
||||
officer = create(:poll_officer)
|
||||
poll = create(:poll)
|
||||
|
||||
booth1 = create(:poll_booth)
|
||||
booth2 = create(:poll_booth)
|
||||
|
||||
ba1 = create(:poll_booth_assignment, poll: poll, booth: booth1)
|
||||
ba2 = create(:poll_booth_assignment, poll: poll, booth: booth2)
|
||||
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba1, date: Date.current)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba2, date: Date.current)
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
expect(page).to have_content "Choose your booth"
|
||||
|
||||
select booth2.location, from: "booth_id"
|
||||
click_button "Enter"
|
||||
|
||||
within("#officing-booth") do
|
||||
expect(page).to have_content "You are officing the booth located at #{booth2.location}."
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Display single booth for any number of polls" do
|
||||
officer = create(:poll_officer)
|
||||
|
||||
booth1 = create(:poll_booth)
|
||||
booth2 = create(:poll_booth)
|
||||
|
||||
poll1 = create(:poll)
|
||||
poll2 = create(:poll)
|
||||
|
||||
ba1 = create(:poll_booth_assignment, poll: poll1, booth: booth1)
|
||||
ba2 = create(:poll_booth_assignment, poll: poll2, booth: booth2)
|
||||
ba3 = create(:poll_booth_assignment, poll: poll2, booth: booth2)
|
||||
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba1, date: Date.current)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba2, date: Date.current)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba3, date: Date.current)
|
||||
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
expect(page).to have_content "Choose your booth"
|
||||
|
||||
expect(page).to have_select("booth_id", options: [booth1.location, booth2.location])
|
||||
end
|
||||
|
||||
end
|
||||
@@ -25,7 +25,7 @@ feature "Residence", :with_frozen_time do
|
||||
|
||||
background do
|
||||
create(:poll_officer_assignment, officer: officer)
|
||||
login_as(officer.user)
|
||||
login_through_form_as_officer(officer.user)
|
||||
visit officing_root_path
|
||||
end
|
||||
|
||||
@@ -93,4 +93,27 @@ feature "Residence", :with_frozen_time do
|
||||
|
||||
end
|
||||
|
||||
scenario "Verify booth", :js do
|
||||
booth = create(:poll_booth)
|
||||
poll = create(:poll)
|
||||
|
||||
ba = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: ba)
|
||||
create(:poll_shift, officer: officer, booth: booth, date: Date.current)
|
||||
|
||||
login_as(officer.user)
|
||||
|
||||
visit new_officing_residence_path
|
||||
within("#officing-booth") do
|
||||
expect(page).to have_content "You are officing the booth located at #{booth.location}."
|
||||
end
|
||||
|
||||
officing_verify_residence
|
||||
|
||||
expect(page).to have_content poll.name
|
||||
click_button "Confirm vote"
|
||||
|
||||
expect(page).to have_content "Vote introduced!"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ feature "Officing Results", :with_frozen_time do
|
||||
background do
|
||||
@poll_officer = create(:poll_officer)
|
||||
@officer_assignment = create(:poll_officer_assignment, :final, officer: @poll_officer)
|
||||
create(:poll_shift, officer: @poll_officer, booth: @officer_assignment.booth, date: Date.current)
|
||||
@poll = @officer_assignment.booth_assignment.poll
|
||||
@poll.update(ends_at: 1.day.ago)
|
||||
@question_1 = create(:poll_question, poll: @poll)
|
||||
@@ -15,6 +16,7 @@ feature "Officing Results", :with_frozen_time do
|
||||
create(:poll_question_answer, title: "Tomorrow", question: @question_2, given_order: 2)
|
||||
|
||||
login_as(@poll_officer.user)
|
||||
set_officing_booth(@officer_assignment.booth)
|
||||
end
|
||||
|
||||
scenario "Only polls where user is officer for results are accessible" do
|
||||
@@ -30,6 +32,7 @@ feature "Officing Results", :with_frozen_time do
|
||||
click_link "Polling officers"
|
||||
|
||||
expect(page).to have_content("Poll officing")
|
||||
|
||||
within("#side_menu") do
|
||||
click_link "Total recounts and results"
|
||||
end
|
||||
|
||||
@@ -12,9 +12,12 @@ feature "Voters" do
|
||||
create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection)
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment)
|
||||
set_officing_booth(booth)
|
||||
end
|
||||
|
||||
scenario "Can vote", :js do
|
||||
create(:poll_officer_assignment, officer: officer)
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
@@ -57,6 +60,10 @@ feature "Voters" do
|
||||
user = create(:user, residence_verified_at: Time.current, document_type: "1", document_number: "12345678Z")
|
||||
expect(user).not_to be_level_two_verified
|
||||
|
||||
visit root_path
|
||||
click_link "Sign out"
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
@@ -83,6 +90,7 @@ feature "Voters" do
|
||||
booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_out, booth: booth)
|
||||
create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment)
|
||||
|
||||
set_officing_booth(second_booth)
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
@@ -93,4 +101,44 @@ feature "Voters" do
|
||||
expect(page).to have_content poll_geozone_restricted_in.name
|
||||
expect(page).not_to have_content poll_geozone_restricted_out.name
|
||||
end
|
||||
|
||||
scenario "Store officer and booth information", :js do
|
||||
create(:user, :in_census, id: rand(9999999))
|
||||
poll1 = create(:poll, name: "¿Quieres que XYZ sea aprobado?")
|
||||
poll2 = create(:poll, name: "Pregunta de votación de prueba")
|
||||
|
||||
second_booth = create(:poll_booth)
|
||||
|
||||
ba1 = create(:poll_booth_assignment, poll: poll1, booth: second_booth )
|
||||
ba2 = create(:poll_booth_assignment, poll: poll2, booth: second_booth )
|
||||
create(:poll_shift, officer: officer, booth: second_booth, date: Date.current, task: :vote_collection)
|
||||
|
||||
validate_officer
|
||||
visit new_officing_residence_path
|
||||
set_officing_booth(second_booth)
|
||||
officing_verify_residence
|
||||
|
||||
within("#poll_#{poll1.id}") do
|
||||
click_button "Confirm vote"
|
||||
|
||||
expect(page).to have_content "Vote introduced!"
|
||||
end
|
||||
|
||||
within("#poll_#{poll2.id}") do
|
||||
click_button "Confirm vote"
|
||||
|
||||
expect(page).to have_content "Vote introduced!"
|
||||
end
|
||||
|
||||
expect(Poll::Voter.count).to eq(2)
|
||||
|
||||
voter1 = Poll::Voter.first
|
||||
|
||||
expect(voter1.booth_assignment).to eq(ba1)
|
||||
expect(voter1.officer_assignment).to eq(ba1.officer_assignments.first)
|
||||
|
||||
voter2 = Poll::Voter.last
|
||||
expect(voter2.booth_assignment).to eq(ba2)
|
||||
expect(voter2.officer_assignment).to eq(ba2.officer_assignments.first)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,6 +97,7 @@ feature "Poll Officing" do
|
||||
end
|
||||
|
||||
scenario "Poll officer access links" do
|
||||
create(:poll)
|
||||
create(:poll_officer, user: user)
|
||||
login_as(user)
|
||||
visit root_path
|
||||
|
||||
@@ -8,6 +8,7 @@ feature "Voter" do
|
||||
let(:question) { create(:poll_question, poll: poll) }
|
||||
let(:booth) { create(:poll_booth) }
|
||||
let(:officer) { create(:poll_officer) }
|
||||
let(:admin) { create(:administrator) }
|
||||
let!(:answer_yes) { create(:poll_question_answer, question: question, title: "Yes") }
|
||||
let!(:answer_no) { create(:poll_question_answer, question: question, title: "No") }
|
||||
|
||||
@@ -71,6 +72,56 @@ feature "Voter" do
|
||||
|
||||
expect(Poll::Voter.count).to eq(1)
|
||||
expect(Poll::Voter.first.origin).to eq("booth")
|
||||
|
||||
visit root_path
|
||||
click_link "Sign out"
|
||||
login_as(admin.user)
|
||||
visit admin_poll_recounts_path(poll)
|
||||
|
||||
within("#total_system") do
|
||||
expect(page).to have_content "1"
|
||||
end
|
||||
|
||||
within("#poll_booth_assignment_#{Poll::BoothAssignment.where(poll: poll, booth: booth).first.id}_recounts") do
|
||||
expect(page).to have_content "1"
|
||||
end
|
||||
end
|
||||
|
||||
context "The person has decided not to vote at this time" do
|
||||
let!(:user) { create(:user, :in_census) }
|
||||
|
||||
scenario "Show not to vote at this time button" do
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
expect(page).to have_content poll.name
|
||||
expect(page).to have_button "Confirm vote"
|
||||
expect(page).to have_content "Can vote"
|
||||
expect(page).to have_link "The person has decided not to vote at this time"
|
||||
end
|
||||
|
||||
scenario "Hides not to vote at this time button if already voted", :js do
|
||||
login_through_form_as_officer(officer.user)
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
within("#poll_#{poll.id}") do
|
||||
click_button("Confirm vote")
|
||||
expect(page).not_to have_button("Confirm vote")
|
||||
expect(page).to have_content "Vote introduced!"
|
||||
expect(page).not_to have_content "The person has decided not to vote at this time"
|
||||
end
|
||||
|
||||
visit new_officing_residence_path
|
||||
officing_verify_residence
|
||||
|
||||
expect(page).to have_content "Has already participated in this poll"
|
||||
expect(page).not_to have_content "The person has decided not to vote at this time"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context "Trying to vote the same poll in booth and web" do
|
||||
@@ -107,6 +158,19 @@ feature "Voter" do
|
||||
expect(page).not_to have_link(answer_yes.title)
|
||||
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)
|
||||
|
||||
visit root_path
|
||||
click_link "Sign out"
|
||||
login_as(admin.user)
|
||||
visit admin_poll_recounts_path(poll)
|
||||
|
||||
within("#total_system") do
|
||||
expect(page).to have_content "1"
|
||||
end
|
||||
|
||||
within("#poll_booth_assignment_#{Poll::BoothAssignment.where(poll: poll, booth: booth).first.id}_recounts") do
|
||||
expect(page).to have_content "1"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Trying to vote in web again", :js do
|
||||
@@ -162,6 +226,19 @@ feature "Voter" do
|
||||
expect(page).not_to have_link(answer_yes.title)
|
||||
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)
|
||||
|
||||
visit root_path
|
||||
click_link "Sign out"
|
||||
login_as(admin.user)
|
||||
visit admin_poll_recounts_path(poll)
|
||||
|
||||
within("#total_system") do
|
||||
expect(page).to have_content "1"
|
||||
end
|
||||
|
||||
within("#poll_booth_assignment_#{Poll::BoothAssignment.where(poll: poll, booth: booth).first.id}_recounts") do
|
||||
expect(page).to have_content "1"
|
||||
end
|
||||
end
|
||||
|
||||
context "Side menu" do
|
||||
|
||||
@@ -1131,4 +1131,91 @@ describe Budget::Investment do
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "scoped_filter" do
|
||||
let(:budget) { create(:budget, phase: "balloting") }
|
||||
let(:investment) { create(:budget_investment, budget: budget) }
|
||||
|
||||
describe "with without_admin filter" do
|
||||
let(:params) { {advanced_filters: ["without_admin"], budget_id: budget.id} }
|
||||
it "returns only investment without admin" do
|
||||
create(:budget_investment,
|
||||
:finished,
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
:with_administrator,
|
||||
budget: budget)
|
||||
investment3 = create(:budget_investment, budget: budget)
|
||||
expect(described_class.scoped_filter(params, "all")).to eq([investment3])
|
||||
expect(described_class.scoped_filter(params, "all").count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with without_valuator filter" do
|
||||
let(:params) { {advanced_filters: ["without_valuator"], budget_id: budget.id} }
|
||||
it "returns only investment without valuator" do
|
||||
create(:budget_investment,
|
||||
:finished,
|
||||
budget: budget)
|
||||
investment2 = create(:budget_investment,
|
||||
:with_administrator,
|
||||
budget: budget)
|
||||
investment3 = create(:budget_investment,
|
||||
budget: budget)
|
||||
expect(described_class.scoped_filter(params, "all"))
|
||||
.to contain_exactly(investment2, investment3)
|
||||
expect(described_class.scoped_filter(params, "all").count)
|
||||
.to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with under_valuation filter" do
|
||||
let(:params) { {advanced_filters: ["under_valuation"], budget_id: budget.id} }
|
||||
it "returns only investment under valuation" do
|
||||
valuator1 = create(:valuator)
|
||||
investment1 = create(:budget_investment,
|
||||
:with_administrator,
|
||||
valuation_finished: false,
|
||||
budget: budget)
|
||||
investment1.valuators << valuator1
|
||||
create(:budget_investment, :with_administrator, budget: budget)
|
||||
create(:budget_investment, budget: budget)
|
||||
|
||||
expect(described_class.scoped_filter(params, "all")).to eq([investment1])
|
||||
expect(described_class.scoped_filter(params, "all").count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with valuation_finished filter" do
|
||||
let(:params) { {advanced_filters: ["valuation_finished"], budget_id: budget.id} }
|
||||
it "returns only investment with valuation finished" do
|
||||
investment1 = create(:budget_investment,
|
||||
:selected,
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
:with_administrator,
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
budget: budget)
|
||||
expect(described_class.scoped_filter(params, "all")).to eq([investment1])
|
||||
expect(described_class.scoped_filter(params, "all").count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with winners filter" do
|
||||
let(:params) { {advanced_filters: ["winners"], budget_id: budget.id} }
|
||||
it "returns only investment winners" do
|
||||
investment1 = create(:budget_investment,
|
||||
:winner,
|
||||
valuation_finished: true,
|
||||
budget: budget)
|
||||
create(:budget_investment,
|
||||
:with_administrator,
|
||||
budget: budget)
|
||||
create(:budget_investment, budget: budget)
|
||||
expect(described_class.scoped_filter(params, "all")).to eq([investment1])
|
||||
expect(described_class.scoped_filter(params, "all").count).to eq(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -121,4 +121,21 @@ describe Poll::Officer do
|
||||
expect(assigned_polls.last).to eq(poll_3)
|
||||
end
|
||||
end
|
||||
|
||||
describe "todays_booths" do
|
||||
let(:officer) { create(:poll_officer) }
|
||||
|
||||
it "returns booths for the application's time zone date", :with_different_time_zone do
|
||||
assignment_with_local_time_zone = create(:poll_officer_assignment,
|
||||
date: Date.today,
|
||||
officer: officer)
|
||||
|
||||
assignment_with_application_time_zone = create(:poll_officer_assignment,
|
||||
date: Date.current,
|
||||
officer: officer)
|
||||
|
||||
expect(officer.todays_booths).to include(assignment_with_application_time_zone.booth)
|
||||
expect(officer.todays_booths).not_to include(assignment_with_local_time_zone.booth)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ describe Poll::Voter do
|
||||
let(:booth) { create(:poll_booth) }
|
||||
let(:booth_assignment) { create(:poll_booth_assignment, poll: poll, booth: booth) }
|
||||
let(:voter) { create(:poll_voter) }
|
||||
let(:officer_assignment) { create(:poll_officer_assignment) }
|
||||
|
||||
describe "validations" do
|
||||
|
||||
@@ -97,6 +98,7 @@ describe Poll::Voter do
|
||||
|
||||
it "is valid with a booth origin" do
|
||||
voter.origin = "booth"
|
||||
voter.officer_assignment = officer_assignment
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
|
||||
@@ -104,7 +106,27 @@ describe Poll::Voter do
|
||||
voter.origin = "web"
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
context "assignments" do
|
||||
it "should not be valid without a booth_assignment_id when origin is booth" do
|
||||
voter.origin = "booth"
|
||||
voter.booth_assignment_id = nil
|
||||
expect(voter).not_to be_valid
|
||||
end
|
||||
|
||||
it "should not be valid without an officer_assignment_id when origin is booth" do
|
||||
voter.origin = "booth"
|
||||
voter.officer_assignment_id = nil
|
||||
expect(voter).not_to be_valid
|
||||
end
|
||||
|
||||
it "should be valid without assignments when origin is web" do
|
||||
voter.origin = "web"
|
||||
voter.booth_assignment_id = nil
|
||||
voter.officer_assignment_id = nil
|
||||
expect(voter).to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -21,4 +21,15 @@ module CommonActions
|
||||
check "user_terms_of_service"
|
||||
end
|
||||
|
||||
def validate_officer
|
||||
allow_any_instance_of(Officing::BaseController).
|
||||
to receive(:verify_officer_assignment).and_return(true)
|
||||
end
|
||||
|
||||
def set_officing_booth(booth=nil)
|
||||
booth = create(:poll_booth) if booth.blank?
|
||||
|
||||
allow_any_instance_of(Officing::BaseController).
|
||||
to receive(:current_booth).and_return(booth)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user