From c9b8a58e3fa1cc211f76f73af4f2e66684733b3f Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 14 Sep 2016 13:53:35 +0200 Subject: [PATCH 001/523] creates polling officers from admin --- .../admin/poll/officers_controller.rb | 32 +++++++++++++ app/helpers/admin_helper.rb | 2 +- app/models/abilities/administrator.rb | 1 + app/models/poll.rb | 2 + app/models/poll/officer.rb | 8 ++++ app/views/admin/_menu.html.erb | 6 +++ app/views/admin/poll/_menu.html.erb | 1 + .../admin/poll/officers/_officer.html.erb | 26 +++++++++++ app/views/admin/poll/officers/index.html.erb | 46 +++++++++++++++++++ app/views/admin/poll/officers/search.js.erb | 1 + .../admin/poll/officers/user_not_found.js.erb | 1 + config/locales/admin.en.yml | 11 +++++ config/locales/admin.es.yml | 11 +++++ config/routes.rb | 6 +++ db/migrate/20160914110004_create_polls.rb | 7 +++ .../20160914110039_create_poll_officers.rb | 7 +++ db/schema.rb | 10 +++- spec/factories.rb | 4 ++ spec/features/admin/poll/officers_spec.rb | 36 +++++++++++++++ 19 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 app/controllers/admin/poll/officers_controller.rb create mode 100644 app/models/poll.rb create mode 100644 app/models/poll/officer.rb create mode 100644 app/views/admin/poll/_menu.html.erb create mode 100644 app/views/admin/poll/officers/_officer.html.erb create mode 100644 app/views/admin/poll/officers/index.html.erb create mode 100644 app/views/admin/poll/officers/search.js.erb create mode 100644 app/views/admin/poll/officers/user_not_found.js.erb create mode 100644 db/migrate/20160914110004_create_polls.rb create mode 100644 db/migrate/20160914110039_create_poll_officers.rb create mode 100644 spec/features/admin/poll/officers_spec.rb diff --git a/app/controllers/admin/poll/officers_controller.rb b/app/controllers/admin/poll/officers_controller.rb new file mode 100644 index 000000000..5495d390c --- /dev/null +++ b/app/controllers/admin/poll/officers_controller.rb @@ -0,0 +1,32 @@ +class Admin::Poll::OfficersController < Admin::BaseController + load_and_authorize_resource :officer, class: "Poll::Officer" + + def index + @officers = @officers.page(params[:page]) + end + + def search + @user = User.find_by(email: params[:email]) + + respond_to do |format| + if @user + @officer = Poll::Officer.find_or_initialize_by(user: @user) + format.js + else + format.js { render "user_not_found" } + end + end + end + + def create + @officer.user_id = params[:user_id] + @officer.save + + redirect_to admin_poll_officers_path + end + + def destroy + @officer.destroy + redirect_to admin_poll_officers_path + end +end \ No newline at end of file diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 515a54deb..39ab74b96 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -19,7 +19,7 @@ module AdminHelper private def namespace - controller.class.parent.name.downcase + controller.class.parent.name.downcase.gsub("::", "/") end end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 0dfce6d3e..0f1100137 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -38,6 +38,7 @@ module Abilities can [:search, :create, :index, :destroy], ::Moderator can [:search, :create, :index, :summary], ::Valuator can [:search, :create, :index, :destroy], ::Manager + can [:search, :create, :index, :destroy], ::Poll::Officer can :manage, Annotation diff --git a/app/models/poll.rb b/app/models/poll.rb new file mode 100644 index 000000000..d815cba49 --- /dev/null +++ b/app/models/poll.rb @@ -0,0 +1,2 @@ +class Poll < ActiveRecord::Base +end \ No newline at end of file diff --git a/app/models/poll/officer.rb b/app/models/poll/officer.rb new file mode 100644 index 000000000..d6fe5730a --- /dev/null +++ b/app/models/poll/officer.rb @@ -0,0 +1,8 @@ +class Poll + class Officer < ActiveRecord::Base + belongs_to :user + delegate :name, :email, to: :user + + validates :user_id, presence: true, uniqueness: true + end +end \ No newline at end of file diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 7ea48b2c6..40bcc6330 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -83,6 +83,12 @@ <% end %> +
  • > + <%= link_to admin_poll_officers_path do %> + <%= t('admin.menu.poll_officers') %> + <% end %> +
  • +
  • > <%= link_to admin_activity_path do %> <%= t('admin.menu.activity') %> diff --git a/app/views/admin/poll/_menu.html.erb b/app/views/admin/poll/_menu.html.erb new file mode 100644 index 000000000..08efd87dc --- /dev/null +++ b/app/views/admin/poll/_menu.html.erb @@ -0,0 +1 @@ +<%= render "admin/menu" %> \ No newline at end of file diff --git a/app/views/admin/poll/officers/_officer.html.erb b/app/views/admin/poll/officers/_officer.html.erb new file mode 100644 index 000000000..c9251548d --- /dev/null +++ b/app/views/admin/poll/officers/_officer.html.erb @@ -0,0 +1,26 @@ +
    + + + + + + + + +
    + <%= officer.name %> + + <%= officer.email %> + + <% if officer.persisted? %> + <%= link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(officer), + method: :delete, + class: "button hollow alert" %> + <% else %> + <%= link_to t('admin.poll_officers.officer.add'),{ controller: "admin/poll/officers", action: :create, user_id: officer.user_id }, + method: :post, + class: "button success" %> + <% end %> +
    +
    diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb new file mode 100644 index 000000000..c330741af --- /dev/null +++ b/app/views/admin/poll/officers/index.html.erb @@ -0,0 +1,46 @@ +

    <%= t("admin.poll_officers.index.title") %>

    + +
    + <%= form_tag search_admin_poll_officers_path, method: :get, remote: true do %> +
    + <%= text_field_tag :email, '', placeholder: t('admin.poll_officers.search.email_placeholder') %> +
    +
    + <%= submit_tag t('admin.poll_officers.search.search'), class: 'button' %> +
    + <% end %> +
    + +
    + +

    <%= page_entries_info @officers %>

    + + + <% @officers.each do |officer| %> + + + + + + <% end %> +
    + <%= officer.name %> + + <%= officer.email %> + + <% if officer.persisted? %> + <%= link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(officer), + method: :delete, + class: "button hollow alert" + %> + <% else %> + <%= link_to t('admin.poll_officers.officer.add'), + { controller: "admin/poll/officers", action: :create, + user_id: officer.user_id }, + method: :post, + class: "button success" %> + <% end %> +
    + +<%= paginate @officers %> diff --git a/app/views/admin/poll/officers/search.js.erb b/app/views/admin/poll/officers/search.js.erb new file mode 100644 index 000000000..bd259f7fb --- /dev/null +++ b/app/views/admin/poll/officers/search.js.erb @@ -0,0 +1 @@ +$("#search-result").html("<%= j render 'officer', officer: @officer %>"); diff --git a/app/views/admin/poll/officers/user_not_found.js.erb b/app/views/admin/poll/officers/user_not_found.js.erb new file mode 100644 index 000000000..108f75295 --- /dev/null +++ b/app/views/admin/poll/officers/user_not_found.js.erb @@ -0,0 +1 @@ +$("#search-result").html("
    <%= j t('admin.officers.search.user_not_found') %>
    "); diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 2f73f64d8..97723c9c8 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -105,6 +105,7 @@ en: managers: Managers moderators: Moderators valuators: Valuators + poll_officers: Poll officers officials: Officials organizations: Organisations settings: Configuration settings @@ -140,6 +141,16 @@ en: in_evaluation_count: In evaluation total_count: Total cost: Cost + poll_officers: + index: + title: Poll officers + officer: + add: Add + delete: Delete + search: + email_placeholder: Search user by email + search: Search + user_not_found: User not found officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 5aada1ce1..f71293208 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -103,6 +103,7 @@ es: managers: Gestores moderators: Moderadores valuators: Evaluadores + poll_officers: Presidentes de mesa officials: Cargos públicos organizations: Organizaciones settings: Configuración global @@ -138,6 +139,16 @@ es: in_evaluation_count: En evaluación total_count: Total cost: Coste total + poll_officers: + index: + title: Presidentes de mesa + officer: + add: Añadir como Presidente de mesa + delete: Borrar + search: + email_placeholder: Buscar usuario por email + search: Buscar + user_not_found: Usuario no encontrado officials: edit: destroy: Eliminar condición de 'Cargo Público' diff --git a/config/routes.rb b/config/routes.rb index 4f3eb94ec..46deae30b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -177,6 +177,12 @@ Rails.application.routes.draw do get :search, on: :collection end + namespace :poll do + resources :officers, only: [:index, :create, :destroy] do + get :search, on: :collection + end + end + resources :verifications, controller: :verifications, only: :index do get :search, on: :collection end diff --git a/db/migrate/20160914110004_create_polls.rb b/db/migrate/20160914110004_create_polls.rb new file mode 100644 index 000000000..9dd67d9ba --- /dev/null +++ b/db/migrate/20160914110004_create_polls.rb @@ -0,0 +1,7 @@ +class CreatePolls < ActiveRecord::Migration + def change + create_table :polls do |t| + t.string :name + end + end +end diff --git a/db/migrate/20160914110039_create_poll_officers.rb b/db/migrate/20160914110039_create_poll_officers.rb new file mode 100644 index 000000000..329220d40 --- /dev/null +++ b/db/migrate/20160914110039_create_poll_officers.rb @@ -0,0 +1,7 @@ +class CreatePollOfficers < ActiveRecord::Migration + def change + create_table :poll_officers do |t| + t.integer :user_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index becde4f8a..082292471 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160803154011) do +ActiveRecord::Schema.define(version: 20160914110039) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -270,6 +270,14 @@ ActiveRecord::Schema.define(version: 20160803154011) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree + create_table "poll_officers", force: :cascade do |t| + t.integer "user_id" + end + + create_table "polls", force: :cascade do |t| + t.string "name" + end + create_table "proposal_notifications", force: :cascade do |t| t.string "title" t.text "body" diff --git a/spec/factories.rb b/spec/factories.rb index cdcfe7381..00884733e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -259,6 +259,10 @@ FactoryGirl.define do user end + factory :poll_officer, class: 'Poll::Officer' do + user + end + factory :organization do user responsible_name "Johnny Utah" diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb new file mode 100644 index 000000000..ed9ec545d --- /dev/null +++ b/spec/features/admin/poll/officers_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +feature 'Admin poll officers' do + background do + @admin = create(:administrator) + @user = create(:user, username: 'Pedro Jose Garcia') + @officer = create(:poll_officer) + login_as(@admin.user) + visit admin_poll_officers_path + end + + scenario 'Index' do + expect(page).to have_content @officer.name + expect(page).to have_content @officer.email + expect(page).to_not have_content @user.name + end + + scenario 'Create poll officer', :js do + fill_in 'email', with: @user.email + click_button 'Search' + + expect(page).to have_content @user.name + click_link 'Add' + within("#officers") do + expect(page).to have_content @user.name + end + end + + scenario 'Delete poll officer' do + click_link 'Delete' + + within("#officers") do + expect(page).to_not have_content @officer.name + end + end +end \ No newline at end of file From cd5266046b0d34600e8910e2d2e5f66382bc1fce Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 14 Sep 2016 14:25:38 +0200 Subject: [PATCH 002/523] fixes translation key --- app/views/admin/poll/officers/user_not_found.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/officers/user_not_found.js.erb b/app/views/admin/poll/officers/user_not_found.js.erb index 108f75295..40b6caac5 100644 --- a/app/views/admin/poll/officers/user_not_found.js.erb +++ b/app/views/admin/poll/officers/user_not_found.js.erb @@ -1 +1 @@ -$("#search-result").html("
    <%= j t('admin.officers.search.user_not_found') %>
    "); +$("#search-result").html("
    <%= j t('admin.poll_officers.search.user_not_found') %>
    "); From b5bebaa6c78df367ec117ef94be584a539dd6a18 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 16 Sep 2016 13:06:30 +0200 Subject: [PATCH 003/523] adds view placeholders for officing polls --- .../admin/poll/booths_controller.rb | 16 ++++++++++++++++ .../admin/poll/officers_controller.rb | 9 ++++++++- app/controllers/admin/poll/polls_controller.rb | 16 ++++++++++++++++ app/controllers/officing/base_controller.rb | 18 ++++++++++++++++++ .../officing/dashboard_controller.rb | 6 ++++++ app/controllers/officing/results_controller.rb | 15 +++++++++++++++ app/controllers/officing/voters_controller.rb | 9 +++++++++ app/views/admin/_menu.html.erb | 16 ++++++++++++++-- app/views/admin/poll/booths/edit.html.erb | 1 + app/views/admin/poll/booths/index.html.erb | 1 + app/views/admin/poll/booths/new.html.erb | 1 + app/views/admin/poll/booths/show.html.erb | 1 + app/views/admin/poll/officers/edit.html.erb | 1 + app/views/admin/poll/officers/show.html.erb | 1 + app/views/admin/poll/polls/edit.html.erb | 1 + app/views/admin/poll/polls/index.html.erb | 1 + app/views/admin/poll/polls/new.html.erb | 1 + app/views/admin/poll/polls/show.html.erb | 1 + app/views/officing/_menu.html.erb | 18 ++++++++++++++++++ app/views/officing/dashboard/index.html.erb | 6 ++++++ app/views/officing/results/index.html.erb | 1 + app/views/officing/results/new.html.erb | 1 + app/views/officing/results/show.html.erb | 1 + app/views/officing/voters/new.html.erb | 1 + app/views/officing/voters/show.html.erb | 1 + app/views/poll/voters/new.html.erb | 1 + app/views/shared/_admin_login_items.html.erb | 6 ++++++ config/locales/admin.en.yml | 2 ++ config/locales/admin.es.yml | 2 ++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/officing.en.yml | 10 ++++++++++ config/locales/officing.es.yml | 10 ++++++++++ config/routes.rb | 17 ++++++++++++++--- 34 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 app/controllers/admin/poll/booths_controller.rb create mode 100644 app/controllers/admin/poll/polls_controller.rb create mode 100644 app/controllers/officing/base_controller.rb create mode 100644 app/controllers/officing/dashboard_controller.rb create mode 100644 app/controllers/officing/results_controller.rb create mode 100644 app/controllers/officing/voters_controller.rb create mode 100644 app/views/admin/poll/booths/edit.html.erb create mode 100644 app/views/admin/poll/booths/index.html.erb create mode 100644 app/views/admin/poll/booths/new.html.erb create mode 100644 app/views/admin/poll/booths/show.html.erb create mode 100644 app/views/admin/poll/officers/edit.html.erb create mode 100644 app/views/admin/poll/officers/show.html.erb create mode 100644 app/views/admin/poll/polls/edit.html.erb create mode 100644 app/views/admin/poll/polls/index.html.erb create mode 100644 app/views/admin/poll/polls/new.html.erb create mode 100644 app/views/admin/poll/polls/show.html.erb create mode 100644 app/views/officing/_menu.html.erb create mode 100644 app/views/officing/dashboard/index.html.erb create mode 100644 app/views/officing/results/index.html.erb create mode 100644 app/views/officing/results/new.html.erb create mode 100644 app/views/officing/results/show.html.erb create mode 100644 app/views/officing/voters/new.html.erb create mode 100644 app/views/officing/voters/show.html.erb create mode 100644 app/views/poll/voters/new.html.erb create mode 100644 config/locales/officing.en.yml create mode 100644 config/locales/officing.es.yml diff --git a/app/controllers/admin/poll/booths_controller.rb b/app/controllers/admin/poll/booths_controller.rb new file mode 100644 index 000000000..9b1e62f8f --- /dev/null +++ b/app/controllers/admin/poll/booths_controller.rb @@ -0,0 +1,16 @@ +class Admin::Poll::BoothsController < Admin::BaseController + skip_authorization_check + + def index + end + + def show + end + + def new + end + + def edit + end + +end \ No newline at end of file diff --git a/app/controllers/admin/poll/officers_controller.rb b/app/controllers/admin/poll/officers_controller.rb index 5495d390c..7f6f918d7 100644 --- a/app/controllers/admin/poll/officers_controller.rb +++ b/app/controllers/admin/poll/officers_controller.rb @@ -1,5 +1,5 @@ class Admin::Poll::OfficersController < Admin::BaseController - load_and_authorize_resource :officer, class: "Poll::Officer" + load_and_authorize_resource :officer, class: "Poll::Officer", except: [:edit, :show] def index @officers = @officers.page(params[:page]) @@ -29,4 +29,11 @@ class Admin::Poll::OfficersController < Admin::BaseController @officer.destroy redirect_to admin_poll_officers_path end + + def show + end + + def edit + end + end \ No newline at end of file diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb new file mode 100644 index 000000000..b90fd2c11 --- /dev/null +++ b/app/controllers/admin/poll/polls_controller.rb @@ -0,0 +1,16 @@ +class Admin::Poll::PollsController < Admin::BaseController + skip_authorization_check + + def index + end + + def show + end + + def new + end + + def edit + end + +end \ No newline at end of file diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb new file mode 100644 index 000000000..5aeb2431c --- /dev/null +++ b/app/controllers/officing/base_controller.rb @@ -0,0 +1,18 @@ +class Officing::BaseController < ActionController::Base + layout 'admin' + + #before_action :verify_officer + before_action :set_locale + + private + + def set_locale + if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym) + session[:locale] = params[:locale] + end + + session[:locale] ||= I18n.default_locale + + I18n.locale = session[:locale] + end +end \ No newline at end of file diff --git a/app/controllers/officing/dashboard_controller.rb b/app/controllers/officing/dashboard_controller.rb new file mode 100644 index 000000000..4d80a974a --- /dev/null +++ b/app/controllers/officing/dashboard_controller.rb @@ -0,0 +1,6 @@ +class Officing::DashboardController < Officing::BaseController + + def index + end + +end diff --git a/app/controllers/officing/results_controller.rb b/app/controllers/officing/results_controller.rb new file mode 100644 index 000000000..03e638366 --- /dev/null +++ b/app/controllers/officing/results_controller.rb @@ -0,0 +1,15 @@ +class Officing::ResultsController < Officing::BaseController + layout 'admin' + + before_action :authenticate_user! + + def index + end + + def show + end + + def new + end + +end \ No newline at end of file diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb new file mode 100644 index 000000000..6d7ad8512 --- /dev/null +++ b/app/controllers/officing/voters_controller.rb @@ -0,0 +1,9 @@ +class Officing::VotersController < Officing::BaseController + layout 'admin' + + before_action :authenticate_user! + + def new + end + +end \ No newline at end of file diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 40bcc6330..48736c378 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -83,12 +83,24 @@ <% end %>
  • -
  • > - <%= link_to admin_poll_officers_path do %> +
  • > + <%= link_to admin_poll_officers_path(Poll.last) do %> <%= t('admin.menu.poll_officers') %> <% end %>
  • +
  • > + <%= link_to admin_polls_path do %> + <%= t('admin.menu.polls') %> + <% end %> +
  • + +
  • > + <%= link_to admin_poll_booths_url(Poll.last) do %> + <%= t('admin.menu.booths') %> + <% end %> +
  • +
  • > <%= link_to admin_activity_path do %> <%= t('admin.menu.activity') %> diff --git a/app/views/admin/poll/booths/edit.html.erb b/app/views/admin/poll/booths/edit.html.erb new file mode 100644 index 000000000..4f66c61cd --- /dev/null +++ b/app/views/admin/poll/booths/edit.html.erb @@ -0,0 +1 @@ +booth edit \ No newline at end of file diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb new file mode 100644 index 000000000..7ef71767d --- /dev/null +++ b/app/views/admin/poll/booths/index.html.erb @@ -0,0 +1 @@ +booth index \ No newline at end of file diff --git a/app/views/admin/poll/booths/new.html.erb b/app/views/admin/poll/booths/new.html.erb new file mode 100644 index 000000000..ebcb88bd4 --- /dev/null +++ b/app/views/admin/poll/booths/new.html.erb @@ -0,0 +1 @@ +booth new \ No newline at end of file diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb new file mode 100644 index 000000000..791a97e48 --- /dev/null +++ b/app/views/admin/poll/booths/show.html.erb @@ -0,0 +1 @@ +booth show \ No newline at end of file diff --git a/app/views/admin/poll/officers/edit.html.erb b/app/views/admin/poll/officers/edit.html.erb new file mode 100644 index 000000000..5c64d3aeb --- /dev/null +++ b/app/views/admin/poll/officers/edit.html.erb @@ -0,0 +1 @@ +officer edit \ No newline at end of file diff --git a/app/views/admin/poll/officers/show.html.erb b/app/views/admin/poll/officers/show.html.erb new file mode 100644 index 000000000..fc702276e --- /dev/null +++ b/app/views/admin/poll/officers/show.html.erb @@ -0,0 +1 @@ +officer show \ No newline at end of file diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb new file mode 100644 index 000000000..ca0a8dc14 --- /dev/null +++ b/app/views/admin/poll/polls/edit.html.erb @@ -0,0 +1 @@ +poll edit \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb new file mode 100644 index 000000000..d01cf64f1 --- /dev/null +++ b/app/views/admin/poll/polls/index.html.erb @@ -0,0 +1 @@ +polls index \ No newline at end of file diff --git a/app/views/admin/poll/polls/new.html.erb b/app/views/admin/poll/polls/new.html.erb new file mode 100644 index 000000000..6e11970d3 --- /dev/null +++ b/app/views/admin/poll/polls/new.html.erb @@ -0,0 +1 @@ +poll new \ No newline at end of file diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb new file mode 100644 index 000000000..61c9d5afb --- /dev/null +++ b/app/views/admin/poll/polls/show.html.erb @@ -0,0 +1 @@ +poll show \ No newline at end of file diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb new file mode 100644 index 000000000..81734d99f --- /dev/null +++ b/app/views/officing/_menu.html.erb @@ -0,0 +1,18 @@ +
    +
      + +
    • > + <%= link_to new_officing_poll_voter_path(Poll.last) do %> + + <%= t("officing.menu.voters") %> + <% end %> +
    • + +
    • > + <%= link_to new_officing_poll_result_path(Poll.last) do %> + + <%= t("officing.menu.results") %> + <% end %> +
    • + +
    diff --git a/app/views/officing/dashboard/index.html.erb b/app/views/officing/dashboard/index.html.erb new file mode 100644 index 000000000..cf014d719 --- /dev/null +++ b/app/views/officing/dashboard/index.html.erb @@ -0,0 +1,6 @@ +
    +

    <%= t("officing.dashboard.index.title") %>

    + +

    <%= t("officing.dashboard.index.info") %>

    + +
    diff --git a/app/views/officing/results/index.html.erb b/app/views/officing/results/index.html.erb new file mode 100644 index 000000000..8e9faa1ab --- /dev/null +++ b/app/views/officing/results/index.html.erb @@ -0,0 +1 @@ +results index \ No newline at end of file diff --git a/app/views/officing/results/new.html.erb b/app/views/officing/results/new.html.erb new file mode 100644 index 000000000..bb40dff9e --- /dev/null +++ b/app/views/officing/results/new.html.erb @@ -0,0 +1 @@ +results new \ No newline at end of file diff --git a/app/views/officing/results/show.html.erb b/app/views/officing/results/show.html.erb new file mode 100644 index 000000000..b3ca8e29c --- /dev/null +++ b/app/views/officing/results/show.html.erb @@ -0,0 +1 @@ +results show \ No newline at end of file diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb new file mode 100644 index 000000000..0fb4c6bc3 --- /dev/null +++ b/app/views/officing/voters/new.html.erb @@ -0,0 +1 @@ +voters new diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb new file mode 100644 index 000000000..fd8c83123 --- /dev/null +++ b/app/views/officing/voters/show.html.erb @@ -0,0 +1 @@ +voters show \ No newline at end of file diff --git a/app/views/poll/voters/new.html.erb b/app/views/poll/voters/new.html.erb new file mode 100644 index 000000000..596b8769c --- /dev/null +++ b/app/views/poll/voters/new.html.erb @@ -0,0 +1 @@ +new.html.erb \ No newline at end of file diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 6ba10bbca..cfe3cc1c9 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -22,4 +22,10 @@ <%= link_to t("layouts.header.management"), management_sign_in_path %>
  • <% end %> + + <%# if current_user.administrator? || current_user.officer? %> +
  • + <%= link_to t("layouts.header.officing"), officing_root_path %> +
  • + <%# end %> <% end %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 97723c9c8..a04595e8b 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -106,6 +106,8 @@ en: moderators: Moderators valuators: Valuators poll_officers: Poll officers + polls: Polls + booths: Booths officials: Officials organizations: Organisations settings: Configuration settings diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index f71293208..ba3548215 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -104,6 +104,8 @@ es: moderators: Moderadores valuators: Evaluadores poll_officers: Presidentes de mesa + polls: Votaciones + booths: Urnas officials: Cargos públicos organizations: Organizaciones settings: Configuración global diff --git a/config/locales/en.yml b/config/locales/en.yml index 3a16722dc..45ec5fac0 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -195,6 +195,7 @@ en: management: Management moderation: Moderation valuation: Valuation + officing: Polling officers more_information: More information my_account_link: My account my_activity_link: My activity diff --git a/config/locales/es.yml b/config/locales/es.yml index 993ee8e95..7cb02f035 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -195,6 +195,7 @@ es: management: Gestión moderation: Moderar valuation: Evaluación + officing: Presidentes de mesa more_information: Más información my_account_link: Mi cuenta my_activity_link: Mi actividad diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml new file mode 100644 index 000000000..532d18498 --- /dev/null +++ b/config/locales/officing.en.yml @@ -0,0 +1,10 @@ +--- +en: + officing: + dashboard: + index: + title: Poll officing + info: Here you can validate user documents and store voting results + menu: + voters: Validate citizen document + results: Store voting results \ No newline at end of file diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml new file mode 100644 index 000000000..baa60b106 --- /dev/null +++ b/config/locales/officing.es.yml @@ -0,0 +1,10 @@ +--- +es: + officing: + dashboard: + index: + title: Presidir mesa de votaciones + info: Aquí puedes validar documentos de ciudadanos y guardar los resultados de las urnas + menu: + voters: Validar documento de identidad + results: Guardar resultados de la votación \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 46deae30b..befbda11e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -177,9 +177,12 @@ Rails.application.routes.draw do get :search, on: :collection end - namespace :poll do - resources :officers, only: [:index, :create, :destroy] do - get :search, on: :collection + scope module: 'poll' do + resources :polls do + resources :booths + resources :officers do + get :search, on: :collection + end end end @@ -266,6 +269,14 @@ Rails.application.routes.draw do end end + namespace :officing do + resources :polls do + resources :voters, only: [:new, :show] + resources :results, only: [:new, :index, :show] + end + root to: "dashboard#index" + end + if Rails.env.development? mount LetterOpenerWeb::Engine, at: "/letter_opener" end From 4ebb4a1104e52552b54f8166160b8e1304aaecb2 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 16 Sep 2016 13:06:39 +0200 Subject: [PATCH 004/523] updates dev_seeds with polls --- db/dev_seeds.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 61b5f5060..beb1d815f 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -336,3 +336,9 @@ Proposal.last(3).each do |proposal| created_at: rand((Time.now - 1.week) .. Time.now)) puts " #{banner.title}" end + +puts "Creating polls" + +3.times.each_with_index do |i| + Poll.create(name: "Poll #{i}") +end \ No newline at end of file From 5ff3e2c5990c1f91b3fdd06c2c5f381cf29b86f5 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Sep 2016 19:07:12 +0200 Subject: [PATCH 005/523] Adds i18n and styles to admin polls index and new --- app/views/admin/poll/polls/index.html.erb | 37 ++++++++++++++++++++++- app/views/admin/poll/polls/new.html.erb | 37 ++++++++++++++++++++++- config/locales/admin.en.yml | 15 +++++++++ config/locales/admin.es.yml | 15 +++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index d01cf64f1..8ba763356 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -1 +1,36 @@ -polls index \ No newline at end of file +

    <%= t("admin.polls.index.title") %>

    + +<%= link_to t("admin.polls.index.create"), new_admin_poll_path, class: "button success float-right" %> + + +
    + <%= t("admin.polls.index.no_polls") %> +
    + + + + + + + + + + + + + + + + + + +
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %> 
    + + <%= link_to "Votación de propuestas 2016", "#" %> + + + Próximamente +
    (15/12/2016 - 15/02/2017) +
    + <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> +
    diff --git a/app/views/admin/poll/polls/new.html.erb b/app/views/admin/poll/polls/new.html.erb index 6e11970d3..b2d74cffc 100644 --- a/app/views/admin/poll/polls/new.html.erb +++ b/app/views/admin/poll/polls/new.html.erb @@ -1 +1,36 @@ -poll new \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.polls.new.title") %>

    + +
    +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + +
    +
    + +
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index a04595e8b..9e267714d 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -9,6 +9,7 @@ en: restore: Restore mark_featured: Featured unmark_featured: Unmark featured + edit: Edit banners: index: title: Banners @@ -153,6 +154,20 @@ en: email_placeholder: Search user by email search: Search user_not_found: User not found + polls: + index: + title: "List of polls" + no_polls: "There are any poll." + create: "Create poll" + name: "Name" + status: "Status" + new: + title: "New poll" + name: "Name" + reference: "Reference number" + open_date: "Open date" + close_date: "Close date" + submit_button: "Create poll" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index ba3548215..a711be773 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -9,6 +9,7 @@ es: restore: Volver a mostrar mark_featured: Destacar unmark_featured: Quitar destacado + edit: Editar banners: index: title: Banners @@ -151,6 +152,20 @@ es: email_placeholder: Buscar usuario por email search: Buscar user_not_found: Usuario no encontrado + polls: + index: + title: "Listado de votaciones" + no_polls: "No hay ninguna votación." + create: "Crear votación" + name: "Nombre" + status: "Estado" + new: + title: "Nueva votación" + name: "Nombre" + reference: "Número de referencia" + open_date: "Fecha de apertura" + close_date: "Fecha de cierre" + submit_button: "Crear votación" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 4872c7a4e86985f29a1767b724769fa3bff1d8e8 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 19 Sep 2016 13:36:42 +0200 Subject: [PATCH 006/523] Adds content to edit and show views --- app/views/admin/poll/polls/edit.html.erb | 37 +++++++++++++++++++- app/views/admin/poll/polls/index.html.erb | 6 ++-- app/views/admin/poll/polls/show.html.erb | 42 ++++++++++++++++++++++- config/locales/admin.en.yml | 15 ++++++-- config/locales/admin.es.yml | 13 +++++++ 5 files changed, 106 insertions(+), 7 deletions(-) diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb index ca0a8dc14..68eb7cc3b 100644 --- a/app/views/admin/poll/polls/edit.html.erb +++ b/app/views/admin/poll/polls/edit.html.erb @@ -1 +1,36 @@ -poll edit \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.polls.edit.title") %>

    + +
    +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + +
    +
    + +
    \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 8ba763356..2f7744c97 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -7,7 +7,7 @@ <%= t("admin.polls.index.no_polls") %> - + @@ -20,7 +20,7 @@ diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 61c9d5afb..9b4971214 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -1 +1,41 @@ -poll show \ No newline at end of file +<%= render "shared/back_link" %> +
    + +

    Votación de propuestas 2016

    +<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +

    (REFNUM)

    +

    Próximamente (15/12/2016 - 15/02/2017)

    +<%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> + + +
    + <%= t("admin.polls.show.no_booths") %> +
    + + +

    <%= t("admin.polls.show.booths_title") %>

    + +
    - <%= link_to "Votación de propuestas 2016", "#" %> + <%= link_to "Votación de propuestas 2016 (REFNUM)", "3" %> @@ -28,7 +28,7 @@
    (15/12/2016 - 15/02/2017)
    - <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> + <%= link_to t("admin.actions.edit"), "3/edit", class: "button hollow" %>
    + + + + + + + + + + + + + + +
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> 
    + + <%= link_to "Urna Moncloa (REFNUM)", "#" %> + + + C/ Isaac Peral, 25. 28003, Madrid + + <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> +
    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 9e267714d..1141aedf3 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -33,8 +33,6 @@ en: editing: Edit banner form: submit_button: Save changes - errors: - form: errors: form: error: @@ -168,6 +166,19 @@ en: open_date: "Open date" close_date: "Close date" submit_button: "Create poll" + edit: + title: "Edit poll" + name: "Name" + reference: "Reference number" + open_date: "Open date" + close_date: "Close date" + submit_button: "Update poll" + show: + no_booths: "There is no booths in this poll." + add_booth: "Add booth" + booths_title: "List of booths" + name: "Name" + location: "Location" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index a711be773..de22029e0 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -166,6 +166,19 @@ es: open_date: "Fecha de apertura" close_date: "Fecha de cierre" submit_button: "Crear votación" + edit: + title: "Editar votación" + name: "Nombre" + reference: "Número de referencia" + open_date: "Fecha de apertura" + close_date: "Fecha de cierre" + submit_button: "Actualizar votación" + show: + no_booths: "No hay urnas en esta votación." + add_booth: "Añadir urna" + booths_title: "Listado de urnas" + name: "Nombre" + location: "Ubicación" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 118d163979f4196fa2f3a09d72e8e112a60b166f Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 17:25:51 +0200 Subject: [PATCH 007/523] hot fix to load last poll on officer's index --- app/views/admin/poll/officers/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index c330741af..56daabb94 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -27,7 +27,7 @@ <% if officer.persisted? %> <%= link_to t('admin.poll_officers.officer.delete'), - admin_poll_officer_path(officer), + admin_poll_officer_path(Poll.last, officer), method: :delete, class: "button hollow alert" %> From fcf7920a40d42766076a7e6b197980127940954f Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 19 Sep 2016 17:26:48 +0200 Subject: [PATCH 008/523] Adds booths index content --- app/views/admin/poll/booths/index.html.erb | 45 +++++++++++++++++++++- config/locales/admin.en.yml | 9 +++++ config/locales/admin.es.yml | 9 +++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 7ef71767d..3af66c042 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -1 +1,44 @@ -booth index \ No newline at end of file +

    <%= t("admin.booths.index.title") %>

    + +
    +
    + +
    +
    + +

    <%= t("admin.booths.index.title_list") %>

    + + +
    + <%= t("admin.booths.index.no_booths") %> +
    + + + + + + + + + + + + + + + + + + +
    <%= t("admin.booths.index.name") %><%= t("admin.booths.index.location") %> 
    + + <%= link_to "Urna Moncloa (REFNUM)", "#" %> + + + C/ Isaac Peral, 25. 28003, Madrid + + <%= link_to t("admin.actions.edit"), "/edit", class: "button hollow" %> + <%= link_to t("admin.booths.index.add_officer"), "/edit", class: "button success" %> +
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 1141aedf3..4c058992d 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -179,6 +179,15 @@ en: booths_title: "List of booths" name: "Name" location: "Location" + booths: + index: + title: "List of booths" + select_poll: "Select a poll" + title_list: "List of booths of poll %{poll}" + no_booths: "There is no booths in this poll." + name: "Name" + location: "Location" + add_officer: "Add officer" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index de22029e0..22fef3006 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -179,6 +179,15 @@ es: booths_title: "Listado de urnas" name: "Nombre" location: "Ubicación" + booths: + index: + title: "Lista de urnas" + select_poll: "Selecciona una votación" + title_list: "Lista de urnas de la votación %{poll}" + no_booths: "No hay urnas en esta votación." + name: "Nombre" + location: "Ubicación" + add_officer: "Añadir presidente" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 5ce886bc6af67131d675a5c5cfa309f0f64aa5fd Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 19 Sep 2016 18:32:21 +0200 Subject: [PATCH 009/523] Add views for admin booths --- app/views/admin/poll/booths/edit.html.erb | 29 ++++++++++++++- app/views/admin/poll/booths/index.html.erb | 9 ++--- app/views/admin/poll/booths/new.html.erb | 29 ++++++++++++++- app/views/admin/poll/booths/show.html.erb | 41 +++++++++++++++++++++- app/views/admin/poll/polls/index.html.erb | 4 +-- config/locales/admin.en.yml | 20 +++++++++++ config/locales/admin.es.yml | 13 +++++++ 7 files changed, 136 insertions(+), 9 deletions(-) diff --git a/app/views/admin/poll/booths/edit.html.erb b/app/views/admin/poll/booths/edit.html.erb index 4f66c61cd..e48db9cdd 100644 --- a/app/views/admin/poll/booths/edit.html.erb +++ b/app/views/admin/poll/booths/edit.html.erb @@ -1 +1,28 @@ -booth edit \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.booths.edit.title") %>: <%= t("admin.booths.edit.subtitle") %>

    + +
    +
    +
    + + +
    + +
    + + +
    + +
    + + "> +
    +
    + +
    +
    + +
    +
    +
    diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 3af66c042..2e9a2f70b 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -14,8 +14,9 @@
    <%= t("admin.booths.index.no_booths") %>
    + - +<%= link_to t("admin.booths.index.add_booth"), new_admin_poll_booth_path, class: "button success" %> @@ -35,10 +36,10 @@ C/ Isaac Peral, 25. 28003, Madrid -
    - <%= link_to t("admin.actions.edit"), "/edit", class: "button hollow" %> - <%= link_to t("admin.booths.index.add_officer"), "/edit", class: "button success" %> + <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> + <%= link_to t("admin.booths.index.add_officer"), "#", class: "button success" %>
    \ No newline at end of file + diff --git a/app/views/admin/poll/booths/new.html.erb b/app/views/admin/poll/booths/new.html.erb index ebcb88bd4..e83d2f47c 100644 --- a/app/views/admin/poll/booths/new.html.erb +++ b/app/views/admin/poll/booths/new.html.erb @@ -1 +1,28 @@ -booth new \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.booths.new.title") %>: <%= t("admin.booths.new.subtitle") %>

    + +
    +
    +
    + + +
    + +
    + + +
    + +
    + + "> +
    +
    + +
    +
    + +
    +
    +
    diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 791a97e48..8a5c2fd99 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -1 +1,40 @@ -booth show \ No newline at end of file +<%= render 'shared/back_link' %> +
    + +

    Urna Moncloa (REFNUM)

    +<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> + +

    <%= t("admin.booths.show.location") %>: C/ Isaac Peral, 25. 28003, Madrid

    + +

    <%= t("admin.booths.show.officers_list") %>

    + + +
    + <%= t("admin.booths.show.no_officers") %> +
    + + +<%= link_to t("admin.booths.show.add_officer"), "#", class: "button success" %> + + + <%# @officers.each do |officer| %> + + + + + + <%# end %> +
    + <%# officer.name %> + Admin + + admin@consul.dev + <%# officer.email %> + + <%= link_to t('admin.poll_officers.officer.delete'), "#", class: "button hollow alert" %> + <%# link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(Poll.last, officer), + method: :delete, + class: "button hollow alert" + %> +
    \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 2f7744c97..c260ab255 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -20,7 +20,7 @@ - <%= link_to "Votación de propuestas 2016 (REFNUM)", "3" %> + <%= link_to "Votación de propuestas 2016 (REFNUM)", "polls/3" %> @@ -28,7 +28,7 @@
    (15/12/2016 - 15/02/2017) - <%= link_to t("admin.actions.edit"), "3/edit", class: "button hollow" %> + <%= link_to t("admin.actions.edit"), "polls/3/edit", class: "button hollow" %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 4c058992d..40822778f 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -185,9 +185,29 @@ en: select_poll: "Select a poll" title_list: "List of booths of poll %{poll}" no_booths: "There is no booths in this poll." + add_booth: "Add booth" name: "Name" location: "Location" add_officer: "Add officer" + new: + title: "Poll %{poll}" + subtitle: "New booth" + name: "Name" + reference: "Reference number" + location: "Location" + submit_button: "Create booth" + edit: + title: "Poll %{poll}" + subtitle: "Edit booth" + name: "Name" + reference: "Reference number" + location: "Location" + submit_button: "Update booth" + show: + location: "Location" + add_officer: "Add officer" + officers_list: "List of officers" + no_officers: "There is no officers in this booth." officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 22fef3006..4c807e454 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -185,9 +185,22 @@ es: select_poll: "Selecciona una votación" title_list: "Lista de urnas de la votación %{poll}" no_booths: "No hay urnas en esta votación." + add_booth: "Añadir urna" name: "Nombre" location: "Ubicación" add_officer: "Añadir presidente" + new: + title: "Votación %{poll}" + subtitle: "Nueva urna" + name: "Nombre" + reference: "Número de referencia" + location: "Ubicación" + submit_button: "Crear urna" + show: + location: "Ubicación" + add_officer: "Añadir presidente de mesa" + officers_list: "Lista de presidentes de mesa" + no_officers: "No hay presidentes de mesa en esta urna." officials: edit: destroy: Eliminar condición de 'Cargo Público' From 0ec3a8e8bf2ed9da59096602506c62e31d974cd5 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 13:31:18 +0200 Subject: [PATCH 010/523] validates voter in census --- app/models/poll/voter.rb | 15 ++++++ config/locales/activerecord.en.yml | 4 ++ config/locales/activerecord.es.yml | 4 ++ .../20160914172016_create_poll_voters.rb | 9 ++++ db/schema.rb | 21 ++++++++- lib/census_api.rb | 18 +++++-- spec/factories.rb | 26 ++++++++++ spec/models/poll/voter_spec.rb | 47 +++++++++++++++++++ 8 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 app/models/poll/voter.rb create mode 100644 db/migrate/20160914172016_create_poll_voters.rb create mode 100644 spec/models/poll/voter_spec.rb diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb new file mode 100644 index 000000000..92df28443 --- /dev/null +++ b/app/models/poll/voter.rb @@ -0,0 +1,15 @@ +class Poll + class Voter < ActiveRecord::Base + belongs_to :booth + + validate :in_census + + def in_census + errors.add(:document_number, :not_in_census) unless census_api_response.valid? + end + + def census_api_response + CensusApi.new.call(document_type, document_number) + end + end +end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 07791e53c..933b0f572 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -82,6 +82,10 @@ en: attributes: max_per_day: invalid: "You have reached the maximum number of private messages per day" + poll/voter: + attributes: + document_number: + not_in_census: "Document not in census" proposal: attributes: tag_list: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index d5b7f0005..38ceeabdd 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -82,6 +82,10 @@ es: attributes: max_per_day: invalid: "Has llegado al número máximo de mensajes privados por día" + poll/voter: + attributes: + document_number: + not_in_census: "Este documento no aparece en el censo" proposal: attributes: tag_list: diff --git a/db/migrate/20160914172016_create_poll_voters.rb b/db/migrate/20160914172016_create_poll_voters.rb new file mode 100644 index 000000000..df5bb4585 --- /dev/null +++ b/db/migrate/20160914172016_create_poll_voters.rb @@ -0,0 +1,9 @@ +class CreatePollVoters < ActiveRecord::Migration + def change + create_table :poll_voters do |t| + t.integer :booth_id + t.string :document_number + t.string :document_type + end + end +end diff --git a/db/schema.rb b/db/schema.rb index becde4f8a..8a928ca79 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160803154011) do +ActiveRecord::Schema.define(version: 20160914172535) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -270,6 +270,25 @@ ActiveRecord::Schema.define(version: 20160803154011) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree + create_table "poll_booths", force: :cascade do |t| + t.string "name" + t.integer "poll_id" + end + + create_table "poll_officers", force: :cascade do |t| + t.integer "user_id" + end + + create_table "poll_voters", force: :cascade do |t| + t.integer "booth_id" + t.string "document_number" + t.string "document_type" + end + + create_table "polls", force: :cascade do |t| + t.string "name" + end + create_table "proposal_notifications", force: :cascade do |t| t.string "title" t.text "body" diff --git a/lib/census_api.rb b/lib/census_api.rb index 678a748c6..d80f420e7 100644 --- a/lib/census_api.rb +++ b/lib/census_api.rb @@ -74,7 +74,7 @@ class CensusApi if end_point_available? client.call(:get_habita_datos, message: request(document_type, document_number)).body else - stubbed_response_body + stubbed_response(document_type, document_number) end end @@ -97,8 +97,20 @@ class CensusApi Rails.env.staging? || Rails.env.preproduction? || Rails.env.production? end - def stubbed_response_body - {get_habita_datos_response: {get_habita_datos_return: {hay_errores: false, datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} + def stubbed_response(document_type, document_number) + if document_number == "12345678Z" && document_type == "1" + stubbed_valid_response + else + stubbed_invalid_response + end + end + + def stubbed_valid_response + {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} + end + + def stubbed_invalid_response + {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {}, datos_vivienda: {}}}} end def is_dni?(document_type) diff --git a/spec/factories.rb b/spec/factories.rb index cdcfe7381..adda53948 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -259,6 +259,32 @@ FactoryGirl.define do user end + factory :poll do + sequence(:name) { |n| "Poll #{n}" } + end + + factory :poll_officer, class: 'Poll::Officer' do + user + end + + factory :poll_booth, class: 'Poll::Booth' do + sequence(:name) { |n| "Booth #{n}" } + poll + end + + factory :poll_voter, class: 'Poll::Voter' do + association :booth, factory: :budget_booth + trait :valid_document do + document_type "1" + document_number "12345678Z" + end + + trait :invalid_document do + document_type "1" + document_number "99999999A" + end + end + factory :organization do user responsible_name "Johnny Utah" diff --git a/spec/models/poll/voter_spec.rb b/spec/models/poll/voter_spec.rb new file mode 100644 index 000000000..de4536243 --- /dev/null +++ b/spec/models/poll/voter_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +describe :voter do + + let(:poll) { create(:poll) } + let(:booth) { create(:poll_booth, poll: poll) } + + describe "validations" do + + it "should be valid if in census and has not voted" do + voter = build(:poll_voter, :valid_document, booth: booth) + + expect(voter).to be_valid + end + + it "should not be valid if the user is not in the census" do + voter = build(:poll_voter, :invalid_document, booth: booth) + + expect(voter).to_not be_valid + expect(voter.errors.messages[:document_number]).to eq(["Document not in census"]) + end + + it "should not be valid if the user has already voted in the same booth" do + voter1 = create(:poll_voter, :valid_document, booth: booth) + voter2 = build(:poll_voter, :valid_document, booth: booth) + + expect(voter2).to_not be_valid + expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) + end + + it "should not be valid if the user has already voted in another booth" do + booth1 = create(:poll_booth, poll: poll) + booth2 = create(:poll_booth, poll: poll) + + voter1 = create(:poll_voter, :valid_document, booth: booth1) + voter2 = build(:poll_voter, :valid_document, booth: booth2) + + expect(voter2).to_not be_valid + expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) + end + + xit "should not be valid if the user has voted via web" do + pending "Implementation for voting via web" + end + + end +end \ No newline at end of file From 48d2aaa845543346ef01bcb8f6c0e70ffd0a6539 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:22:35 +0200 Subject: [PATCH 011/523] validates user has not already voted --- app/models/poll.rb | 4 ++++ app/models/poll/booth.rb | 6 ++++++ app/models/poll/voter.rb | 11 +++++++++++ config/locales/activerecord.en.yml | 1 + config/locales/activerecord.es.yml | 1 + db/migrate/20160914172535_create_poll_booths.rb | 8 ++++++++ 6 files changed, 31 insertions(+) create mode 100644 app/models/poll.rb create mode 100644 app/models/poll/booth.rb create mode 100644 db/migrate/20160914172535_create_poll_booths.rb diff --git a/app/models/poll.rb b/app/models/poll.rb new file mode 100644 index 000000000..507c848aa --- /dev/null +++ b/app/models/poll.rb @@ -0,0 +1,4 @@ +class Poll < ActiveRecord::Base + has_many :booths + has_many :voters, through: :booths, class_name: "Poll::Voter" +end \ No newline at end of file diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb new file mode 100644 index 000000000..a05f3d547 --- /dev/null +++ b/app/models/poll/booth.rb @@ -0,0 +1,6 @@ +class Poll + class Booth < ActiveRecord::Base + belongs_to :poll + has_many :voters + end +end \ No newline at end of file diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 92df28443..353d593b3 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,15 +1,26 @@ class Poll class Voter < ActiveRecord::Base belongs_to :booth + delegate :poll, to: :booth validate :in_census + validate :has_not_voted def in_census errors.add(:document_number, :not_in_census) unless census_api_response.valid? end + def has_not_voted + errors.add(:document_number, :has_voted) if has_voted? + end + def census_api_response CensusApi.new.call(document_type, document_number) end + + def has_voted? + poll.voters.where(document_number: document_number, document_type: document_type).present? + end + end end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 933b0f572..252feb0b5 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -86,6 +86,7 @@ en: attributes: document_number: not_in_census: "Document not in census" + has_voted: "Has already voted" proposal: attributes: tag_list: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 38ceeabdd..18faf7900 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -86,6 +86,7 @@ es: attributes: document_number: not_in_census: "Este documento no aparece en el censo" + has_voted: "Ya ha votado" proposal: attributes: tag_list: diff --git a/db/migrate/20160914172535_create_poll_booths.rb b/db/migrate/20160914172535_create_poll_booths.rb new file mode 100644 index 000000000..a474aba49 --- /dev/null +++ b/db/migrate/20160914172535_create_poll_booths.rb @@ -0,0 +1,8 @@ +class CreatePollBooths < ActiveRecord::Migration + def change + create_table :poll_booths do |t| + t.string :name + t.integer :poll_id + end + end +end From 88e7af70d05d9d3490b94b41fd0dbba04c0159c3 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:37:37 +0200 Subject: [PATCH 012/523] displays voter name if already voted --- app/models/poll/voter.rb | 8 ++++++-- config/locales/activerecord.en.yml | 2 +- config/locales/activerecord.es.yml | 2 +- lib/census_api.rb | 6 +++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 353d593b3..936d8af3b 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -11,16 +11,20 @@ class Poll end def has_not_voted - errors.add(:document_number, :has_voted) if has_voted? + errors.add(:document_number, :has_voted, name: name) if has_voted? end def census_api_response - CensusApi.new.call(document_type, document_number) + @census ||= CensusApi.new.call(document_type, document_number) end def has_voted? poll.voters.where(document_number: document_number, document_type: document_type).present? end + def name + @census.name + end + end end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 252feb0b5..32f4ef78f 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -86,7 +86,7 @@ en: attributes: document_number: not_in_census: "Document not in census" - has_voted: "Has already voted" + has_voted: "%{name} has already voted" proposal: attributes: tag_list: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 18faf7900..a9047df7b 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -86,7 +86,7 @@ es: attributes: document_number: not_in_census: "Este documento no aparece en el censo" - has_voted: "Ya ha votado" + has_voted: "%{name} ya ha votado" proposal: attributes: tag_list: diff --git a/lib/census_api.rb b/lib/census_api.rb index d80f420e7..eadfc549e 100644 --- a/lib/census_api.rb +++ b/lib/census_api.rb @@ -61,6 +61,10 @@ class CensusApi end end + def name + "#{data[:datos_habitante][:item][:nombre]} #{data[:datos_habitante][:item][:apellido1]}" + end + private def data @@ -106,7 +110,7 @@ class CensusApi end def stubbed_valid_response - {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} + {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón", nombre: "José", apellido1: "García" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} end def stubbed_invalid_response From 4c08058f80fdd710fa7050ede646d1bc2c0873db Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:54:02 +0200 Subject: [PATCH 013/523] updates db schema --- db/schema.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 8a928ca79..e68f466ce 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -275,10 +275,6 @@ ActiveRecord::Schema.define(version: 20160914172535) do t.integer "poll_id" end - create_table "poll_officers", force: :cascade do |t| - t.integer "user_id" - end - create_table "poll_voters", force: :cascade do |t| t.integer "booth_id" t.string "document_number" From 55f4a6bbae019fdd8fd9f497b649e51ac14339c5 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:55:16 +0200 Subject: [PATCH 014/523] removes officer factory --- spec/factories.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index adda53948..48162288d 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -263,10 +263,6 @@ FactoryGirl.define do sequence(:name) { |n| "Poll #{n}" } end - factory :poll_officer, class: 'Poll::Officer' do - user - end - factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } poll From e0951a2f2d968e76f8d065eb4899cd703d12f110 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:56:10 +0200 Subject: [PATCH 015/523] adds spacing to factories --- spec/factories.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/factories.rb b/spec/factories.rb index 48162288d..cea46a0bc 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -270,6 +270,7 @@ FactoryGirl.define do factory :poll_voter, class: 'Poll::Voter' do association :booth, factory: :budget_booth + trait :valid_document do document_type "1" document_number "12345678Z" From a6384af527126e61c972ce3fe791b7ee4259162e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 20 Sep 2016 11:44:43 +0200 Subject: [PATCH 016/523] updates query to be more efficient --- app/models/poll/voter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 936d8af3b..a517c3f34 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -19,7 +19,7 @@ class Poll end def has_voted? - poll.voters.where(document_number: document_number, document_type: document_type).present? + poll.voters.where(document_number: document_number, document_type: document_type).exists? end def name From 7781edf879e8e8595f87bab8d8c9c876a6e166d9 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 20 Sep 2016 12:32:23 +0200 Subject: [PATCH 017/523] Adds content to booths index and show views --- app/views/admin/poll/booths/index.html.erb | 9 ++++++--- app/views/admin/poll/booths/show.html.erb | 14 ++++++++++++-- config/locales/admin.en.yml | 4 ++-- config/locales/admin.es.yml | 11 +++++++++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 2e9a2f70b..918479f38 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -22,6 +22,7 @@ <%= t("admin.booths.index.name") %> <%= t("admin.booths.index.location") %> + <%= t("admin.booths.index.officers") %>   @@ -29,15 +30,17 @@ - <%= link_to "Urna Moncloa (REFNUM)", "#" %> + <%= link_to "Urna Moncloa (REFNUM)", "booths/1" %> C/ Isaac Peral, 25. 28003, Madrid + + N <%= t("admin.booths.index.officers") %> + - <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> - <%= link_to t("admin.booths.index.add_officer"), "#", class: "button success" %> + <%= link_to t("admin.actions.edit"), "booths/1/edit", class: "button hollow" %> diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 8a5c2fd99..34e1a4465 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -2,7 +2,7 @@

    Urna Moncloa (REFNUM)

    -<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +<%= link_to t("admin.actions.edit"), "1/edit", class: "button hollow float-right" %>

    <%= t("admin.booths.show.location") %>: C/ Isaac Peral, 25. 28003, Madrid

    @@ -14,7 +14,17 @@ -<%= link_to t("admin.booths.show.add_officer"), "#", class: "button success" %> +<%= link_to t("admin.booths.show.assign_officer"), "#", class: "button success" %> + +
    + + <%# f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %> + + <%# f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %> + <%# b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %> + <%# end %> +
    <%# @officers.each do |officer| %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 40822778f..40f959a3a 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -188,7 +188,7 @@ en: add_booth: "Add booth" name: "Name" location: "Location" - add_officer: "Add officer" + officers: "Officers" new: title: "Poll %{poll}" subtitle: "New booth" @@ -205,7 +205,7 @@ en: submit_button: "Update booth" show: location: "Location" - add_officer: "Add officer" + assign_officer: "Assign officer" officers_list: "List of officers" no_officers: "There is no officers in this booth." officials: diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 4c807e454..6023da712 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -188,7 +188,7 @@ es: add_booth: "Añadir urna" name: "Nombre" location: "Ubicación" - add_officer: "Añadir presidente" + officers: "Presidentes de mesa" new: title: "Votación %{poll}" subtitle: "Nueva urna" @@ -196,9 +196,16 @@ es: reference: "Número de referencia" location: "Ubicación" submit_button: "Crear urna" + edit: + title: "Votación %{poll}" + subtitle: "Editar urna" + name: "Nombre" + reference: "Número de referencia" + location: "Ubicación" + submit_button: "Actualizar urna" show: location: "Ubicación" - add_officer: "Añadir presidente de mesa" + assign_officer: "Asignar presidente de mesa" officers_list: "Lista de presidentes de mesa" no_officers: "No hay presidentes de mesa en esta urna." officials: From fd220bdf22ab0db91de0af7adae386b00bc59cd0 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 20 Sep 2016 13:49:48 +0200 Subject: [PATCH 018/523] fixes specs --- spec/features/management/document_verifications_spec.rb | 4 ++-- spec/features/management/email_verifications_spec.rb | 4 ++-- spec/features/management/managed_users_spec.rb | 4 ++-- spec/features/management/users_spec.rb | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/features/management/document_verifications_spec.rb b/spec/features/management/document_verifications_spec.rb index 674349815..130630762 100644 --- a/spec/features/management/document_verifications_spec.rb +++ b/spec/features/management/document_verifications_spec.rb @@ -47,7 +47,7 @@ feature 'DocumentVerifications' do scenario 'Verifying a user which does exists in the census but not in the db redirects allows sending an email' do visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" @@ -66,7 +66,7 @@ feature 'DocumentVerifications' do expect_any_instance_of(Verification::Management::Document).to receive(:under_sixteen?).and_return(true) visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "You must be over 16 to verify your account." diff --git a/spec/features/management/email_verifications_spec.rb b/spec/features/management/email_verifications_spec.rb index 22987f317..d68d9bd5f 100644 --- a/spec/features/management/email_verifications_spec.rb +++ b/spec/features/management/email_verifications_spec.rb @@ -8,7 +8,7 @@ feature 'EmailVerifications' do user = create(:user) visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" @@ -30,7 +30,7 @@ feature 'EmailVerifications' do expect(page).to_not have_link "Verify my account" expect(page).to have_content "Account verified" - expect(user.reload.document_number).to eq('1234') + expect(user.reload.document_number).to eq('12345678Z') expect(user).to be_level_three_verified end diff --git a/spec/features/management/managed_users_spec.rb b/spec/features/management/managed_users_spec.rb index 78010bc39..6ac04b137 100644 --- a/spec/features/management/managed_users_spec.rb +++ b/spec/features/management/managed_users_spec.rb @@ -57,7 +57,7 @@ feature 'Managed User' do user = create(:user) visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' within(".account-info") do @@ -88,7 +88,7 @@ feature 'Managed User' do login_as_manager visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" diff --git a/spec/features/management/users_spec.rb b/spec/features/management/users_spec.rb index 1a0618e60..694720cc0 100644 --- a/spec/features/management/users_spec.rb +++ b/spec/features/management/users_spec.rb @@ -9,7 +9,7 @@ feature 'Users' do scenario 'Create a level 3 user from scratch' do visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" @@ -45,10 +45,10 @@ feature 'Users' do end scenario 'Delete a level 2 user account from document verification page', :js do - level_2_user = create(:user, :level_two, document_number: 13579) + level_2_user = create(:user, :level_two, document_number: "12345678Z") visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '13579' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to_not have_content "This user account is already verified." @@ -62,7 +62,7 @@ feature 'Users' do expect(level_2_user.reload.erase_reason).to eq "Deleted by manager: manager_user_#{Manager.last.user_id}" visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '13579' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "no user account associated to it" From c965e2dda1526755ad96423442c8f4785e1293b6 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 23 Sep 2016 09:13:02 +0200 Subject: [PATCH 019/523] tmp commit poll index, show and new --- .../admin/poll/polls_controller.rb | 2 +- app/models/abilities/administrator.rb | 2 + app/views/admin/poll/polls/_poll.html.erb | 16 ++++++++ app/views/admin/poll/polls/index.html.erb | 17 +------- app/views/admin/poll/polls/show.html.erb | 6 ++- spec/features/admin/poll/polls_spec.rb | 40 +++++++++++++++++++ 6 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 app/views/admin/poll/polls/_poll.html.erb create mode 100644 spec/features/admin/poll/polls_spec.rb diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index b90fd2c11..eb8b417b8 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -1,5 +1,5 @@ class Admin::Poll::PollsController < Admin::BaseController - skip_authorization_check + load_and_authorize_resource def index end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 0f1100137..bd74e1be9 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -40,6 +40,8 @@ module Abilities can [:search, :create, :index, :destroy], ::Manager can [:search, :create, :index, :destroy], ::Poll::Officer + can [:manage], Poll + can :manage, Annotation can [:read, :update, :destroy, :summary], SpendingProposal diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb new file mode 100644 index 000000000..a9f2dcd1b --- /dev/null +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index c260ab255..b24cc10f6 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -16,21 +16,6 @@ - - - - - - - + <%= render @polls %>
    + + <%= link_to poll.name, admin_poll_path(poll) %> + ß + + Próximamente +
    (15/12/2016 - 15/02/2017) +
    + <%= link_to t("admin.actions.edit"), + edit_admin_poll_path(poll), + class: "button hollow" %> +
     
    - - <%= link_to "Votación de propuestas 2016 (REFNUM)", "polls/3" %> - - - Próximamente -
    (15/12/2016 - 15/02/2017) -
    - <%= link_to t("admin.actions.edit"), "polls/3/edit", class: "button hollow" %> -
    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 9b4971214..105cf2fe6 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -1,8 +1,12 @@ <%= render "shared/back_link" %>
    -

    Votación de propuestas 2016

    +

    + <%= @poll.name %> +

    + <%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +

    (REFNUM)

    Próximamente (15/12/2016 - 15/02/2017)

    <%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb new file mode 100644 index 000000000..a94c81cc9 --- /dev/null +++ b/spec/features/admin/poll/polls_spec.rb @@ -0,0 +1,40 @@ +require 'rails_helper' + +feature 'Admin polls' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'Index' do + 3.times { create(:poll) } + + visit admin_root_path + + within('#side_menu') do + click_link "Polls" + end + + expect(page).to have_css ".poll", count: 3 + + Poll.all.each do |poll| + within("#poll_#{poll.id}") do + expect(page).to have_content poll.name +#expect(page).to have_content "Status/Dates" - Hardcoded + end + end + end + + scenario 'Show', :focus do + poll = create(:poll) + + visit admin_polls_path + click_link poll.name + + expect(page).to have_content poll.name +#expect(page).to have_content "Status/Dates" - Hardcoded +#expect(page).to have_content "REFNUM" - Hardcoded + end + +end \ No newline at end of file From 0795da02d8c5d2b44c35ca304c290fc7cd3ad3f4 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:20:38 +0200 Subject: [PATCH 020/523] adds poll CRU actions --- .../admin/poll/polls_controller.rb | 22 ++++++++ app/models/poll.rb | 2 + app/views/admin/poll/polls/_form.html.erb | 34 ++++++++++++ app/views/admin/poll/polls/_poll.html.erb | 2 +- app/views/admin/poll/polls/edit.html.erb | 5 +- app/views/admin/poll/polls/index.html.erb | 37 ++++++------- app/views/admin/poll/polls/new.html.erb | 33 +----------- app/views/admin/poll/polls/show.html.erb | 6 +-- config/locales/admin.en.yml | 2 +- config/locales/responders.en.yml | 3 +- config/locales/responders.es.yml | 1 + spec/features/admin/poll/polls_spec.rb | 53 ++++++++++++++++++- spec/models/poll_spec.rb | 16 ++++++ 13 files changed, 157 insertions(+), 59 deletions(-) create mode 100644 app/views/admin/poll/polls/_form.html.erb create mode 100644 spec/models/poll_spec.rb diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index eb8b417b8..2a7c1e730 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -10,7 +10,29 @@ class Admin::Poll::PollsController < Admin::BaseController def new end + def create + if @poll.save + redirect_to [:admin, @poll], notice: t("flash.actions.create.poll") + else + render :new + end + end + def edit end + def update + if @poll.update(poll_params) + redirect_to [:admin, @poll], notice: t("flash.actions.update.poll") + else + render :edit + end + end + + private + + def poll_params + params.require(:poll).permit(:name) + end + end \ No newline at end of file diff --git a/app/models/poll.rb b/app/models/poll.rb index 507c848aa..4543a2544 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,4 +1,6 @@ class Poll < ActiveRecord::Base has_many :booths has_many :voters, through: :booths, class_name: "Poll::Voter" + + validates :name, presence: true end \ No newline at end of file diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb new file mode 100644 index 000000000..64d7177a6 --- /dev/null +++ b/app/views/admin/poll/polls/_form.html.erb @@ -0,0 +1,34 @@ +<%= form_for [:admin, @poll] do |f| %> +
    +
    + <%= f.text_field :name, + placeholder: t('admin.polls.new.name'), + label: t("admin.polls.new.name") %> +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + +
    +
    +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index a9f2dcd1b..4128ad222 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -2,7 +2,7 @@ <%= link_to poll.name, admin_poll_path(poll) %> - ß + Próximamente diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb index 68eb7cc3b..0158655a5 100644 --- a/app/views/admin/poll/polls/edit.html.erb +++ b/app/views/admin/poll/polls/edit.html.erb @@ -1,8 +1,9 @@ <%= render 'shared/back_link' %>

    <%= t("admin.polls.edit.title") %>

    +<%= render "form" %> -
    +
    \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index b24cc10f6..2954e44b8 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -1,21 +1,22 @@

    <%= t("admin.polls.index.title") %>

    -<%= link_to t("admin.polls.index.create"), new_admin_poll_path, class: "button success float-right" %> +<%= link_to t("admin.polls.index.create"), + new_admin_poll_path, + class: "button success float-right" %> - -
    - <%= t("admin.polls.index.no_polls") %> -
    - - - - - - - - - - - <%= render @polls %> - -
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %> 
    +<% if Poll.any? %> + + + + + + + + <%= render @polls %> + +
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %> 
    +<% else %> +
    + <%= t("admin.polls.index.no_polls") %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/new.html.erb b/app/views/admin/poll/polls/new.html.erb index b2d74cffc..ba1ae7260 100644 --- a/app/views/admin/poll/polls/new.html.erb +++ b/app/views/admin/poll/polls/new.html.erb @@ -2,35 +2,4 @@

    <%= t("admin.polls.new.title") %>

    -
    -
    -
    - - -
    - -
    - - -
    -
    - -
    -
    - - -
    - -
    - - -
    -
    - -
    -
    - -
    -
    - -
    \ No newline at end of file +<%= render "form" %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 105cf2fe6..1b0d1e198 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -5,7 +5,7 @@ <%= @poll.name %> -<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +<%= link_to t("admin.actions.edit"), edit_admin_poll_path(@poll), class: "button hollow float-right" %>

    (REFNUM)

    Próximamente (15/12/2016 - 15/02/2017)

    @@ -26,7 +26,7 @@   - + <%= @poll.booths.each do |booth| %> @@ -40,6 +40,6 @@ <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> - + <% end %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 40f959a3a..bb8093b03 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -155,7 +155,7 @@ en: polls: index: title: "List of polls" - no_polls: "There are any poll." + no_polls: "There are no polls." create: "Create poll" name: "Name" status: "Status" diff --git a/config/locales/responders.en.yml b/config/locales/responders.en.yml index ab1641799..422a59e0c 100755 --- a/config/locales/responders.en.yml +++ b/config/locales/responders.en.yml @@ -6,15 +6,16 @@ en: notice: "%{resource_name} created successfully." debate: "Debate created successfully." direct_message: "You message has been sent successfully." + poll: "Poll created successfully." proposal: "Proposal created successfully." proposal_notification: "Your message has been sent correctly." spending_proposal: "Spending proposal created successfully. You can access it from %{activity}" - save_changes: notice: Changes saved update: notice: "%{resource_name} updated successfully." debate: "Debate updated successfully." + poll: "Poll updated successfully." proposal: "Proposal updated successfully." spending_proposal: "Investment project updated succesfully." destroy: diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index 387085d69..c9292b187 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -6,6 +6,7 @@ es: notice: "%{resource_name} creado correctamente." debate: "Debate creado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente." + poll: "Votación presencial creada correctamente." proposal: "Propuesta creada correctamente." proposal_notification: "Tu message ha sido enviado correctamente." spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}" diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index a94c81cc9..8d130e67a 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -7,6 +7,15 @@ feature 'Admin polls' do login_as(admin.user) end + scenario 'Index empty' do + visit admin_root_path + within('#side_menu') do + click_link "Polls" + end + + expect(page).to have_content "There are no polls" + end + scenario 'Index' do 3.times { create(:poll) } @@ -24,9 +33,10 @@ feature 'Admin polls' do #expect(page).to have_content "Status/Dates" - Hardcoded end end + expect(page).to_not have_content "There are no polls" end - scenario 'Show', :focus do + scenario 'Show' do poll = create(:poll) visit admin_polls_path @@ -37,4 +47,45 @@ feature 'Admin polls' do #expect(page).to have_content "REFNUM" - Hardcoded end + scenario "Create" do + visit admin_polls_path + click_link "Create poll" + + fill_in "poll_name", with: "Upcoming poll" +#fill_in reference_number - Hardcoded +#fill_in open_date - Hardcoded +#fill_in close_date - Hardcoded + click_button "Create poll" + expect(page).to have_content "Poll created successfully" + + expect(page).to have_content "Upcoming poll" + end + + scenario "Edit" do + poll = create(:poll) + + visit admin_poll_path(poll) + click_link "Edit" +save_and_open_page + fill_in "poll_name", with: "Next Poll" +#fill_in reference_number - Hardcoded +#fill_in open_date - Hardcoded +#fill_in close_date - Hardcoded + click_button "Update poll" + expect(page).to have_content "Poll updated successfully" + + expect(page).to have_content "Next Poll" + end + + scenario 'Edit from index' do + poll = create(:poll) + visit admin_polls_path + + within("#poll_#{poll.id}") do + click_link "Edit" + end + + expect(current_path).to eq(edit_admin_poll_path(poll)) + end + end \ No newline at end of file diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb new file mode 100644 index 000000000..7442cdc5a --- /dev/null +++ b/spec/models/poll_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +describe :poll do + + let(:poll) { build(:poll) } + + it "should be valid" do + expect(poll).to be_valid + end + + it "should not be valid without a name" do + poll.name = nil + expect(poll).to_not be_valid + end + +end \ No newline at end of file From 04c58135eec41d72f5554a87bb5dbb6b192e51de Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:21:34 +0200 Subject: [PATCH 021/523] adds admin submit button helper --- app/helpers/admin_helper.rb | 4 ++++ spec/helpers/admin_helper_spec.rb | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 spec/helpers/admin_helper_spec.rb diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 39ab74b96..f14269fb3 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -16,6 +16,10 @@ module AdminHelper Administrator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] } end + def admin_submit_action(resource) + resource.persisted? ? "edit" : "new" + end + private def namespace diff --git a/spec/helpers/admin_helper_spec.rb b/spec/helpers/admin_helper_spec.rb new file mode 100644 index 000000000..0239f1926 --- /dev/null +++ b/spec/helpers/admin_helper_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +describe AdminHelper do + + describe "#admin_submit_action" do + + it "returns new when the the resource has not been persisted" do + poll = build(:poll) + expect(admin_submit_action(poll)).to eq("new") + end + + it "returns edit when the the resource has been persisted" do + poll = create(:poll) + expect(admin_submit_action(poll)).to eq("edit") + end + + end + +end \ No newline at end of file From e2a0b051e91ef76fa9c8657742c29fcef97dd22d Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:21:58 +0200 Subject: [PATCH 022/523] allow officers to be created without a poll --- app/controllers/admin/poll/officers_controller.rb | 4 ++-- app/views/admin/_menu.html.erb | 14 ++++++++------ app/views/admin/poll/officers/index.html.erb | 4 ++-- config/routes.rb | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/controllers/admin/poll/officers_controller.rb b/app/controllers/admin/poll/officers_controller.rb index 7f6f918d7..2641a12b5 100644 --- a/app/controllers/admin/poll/officers_controller.rb +++ b/app/controllers/admin/poll/officers_controller.rb @@ -22,12 +22,12 @@ class Admin::Poll::OfficersController < Admin::BaseController @officer.user_id = params[:user_id] @officer.save - redirect_to admin_poll_officers_path + redirect_to admin_officers_path end def destroy @officer.destroy - redirect_to admin_poll_officers_path + redirect_to admin_officers_path end def show diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 48736c378..0661a3bb6 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -84,7 +84,7 @@
  • > - <%= link_to admin_poll_officers_path(Poll.last) do %> + <%= link_to admin_officers_path do %> <%= t('admin.menu.poll_officers') %> <% end %>
  • @@ -95,11 +95,13 @@ <% end %> -
  • > - <%= link_to admin_poll_booths_url(Poll.last) do %> - <%= t('admin.menu.booths') %> - <% end %> -
  • + <% if Poll.any? %> +
  • > + <%= link_to admin_poll_booths_url(Poll.last) do %> + <%= t('admin.menu.booths') %> + <% end %> +
  • + <% end %>
  • > <%= link_to admin_activity_path do %> diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index 56daabb94..cc6393204 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -1,7 +1,7 @@

    <%= t("admin.poll_officers.index.title") %>

    - <%= form_tag search_admin_poll_officers_path, method: :get, remote: true do %> + <%= form_tag search_admin_officers_path, method: :get, remote: true do %>
    <%= text_field_tag :email, '', placeholder: t('admin.poll_officers.search.email_placeholder') %>
    @@ -27,7 +27,7 @@ <% if officer.persisted? %> <%= link_to t('admin.poll_officers.officer.delete'), - admin_poll_officer_path(Poll.last, officer), + admin_officer_path(officer), method: :delete, class: "button hollow alert" %> diff --git a/config/routes.rb b/config/routes.rb index befbda11e..070823d63 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -178,11 +178,11 @@ Rails.application.routes.draw do end scope module: 'poll' do + resources :officers do + get :search, on: :collection + end resources :polls do resources :booths - resources :officers do - get :search, on: :collection - end end end From a7279d2d67d6a6a7814d9908444adc3313b38bc1 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:26:32 +0200 Subject: [PATCH 023/523] removes poll unused attributes --- app/views/admin/poll/polls/_form.html.erb | 22 ++------------- app/views/admin/poll/polls/edit.html.erb | 34 +---------------------- spec/features/admin/poll/polls_spec.rb | 19 ++++--------- 3 files changed, 8 insertions(+), 67 deletions(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 64d7177a6..77961912c 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -5,30 +5,12 @@ placeholder: t('admin.polls.new.name'), label: t("admin.polls.new.name") %>
    - -
    - - -
    - - -
    -
    - - -
    - -
    - - -
    - + <%= f.submit t("admin.polls.#{admin_submit_action(@poll)}.submit_button"), + class: "button success expanded" %>
    <% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb index 0158655a5..cf131203f 100644 --- a/app/views/admin/poll/polls/edit.html.erb +++ b/app/views/admin/poll/polls/edit.html.erb @@ -1,37 +1,5 @@ <%= render 'shared/back_link' %>

    <%= t("admin.polls.edit.title") %>

    -<%= render "form" %> - - - \ No newline at end of file +<%= render "form" %> \ No newline at end of file diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 8d130e67a..bab7b5847 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -30,7 +30,6 @@ feature 'Admin polls' do Poll.all.each do |poll| within("#poll_#{poll.id}") do expect(page).to have_content poll.name -#expect(page).to have_content "Status/Dates" - Hardcoded end end expect(page).to_not have_content "There are no polls" @@ -43,8 +42,6 @@ feature 'Admin polls' do click_link poll.name expect(page).to have_content poll.name -#expect(page).to have_content "Status/Dates" - Hardcoded -#expect(page).to have_content "REFNUM" - Hardcoded end scenario "Create" do @@ -52,12 +49,9 @@ feature 'Admin polls' do click_link "Create poll" fill_in "poll_name", with: "Upcoming poll" -#fill_in reference_number - Hardcoded -#fill_in open_date - Hardcoded -#fill_in close_date - Hardcoded click_button "Create poll" - expect(page).to have_content "Poll created successfully" + expect(page).to have_content "Poll created successfully" expect(page).to have_content "Upcoming poll" end @@ -66,14 +60,11 @@ feature 'Admin polls' do visit admin_poll_path(poll) click_link "Edit" -save_and_open_page - fill_in "poll_name", with: "Next Poll" -#fill_in reference_number - Hardcoded -#fill_in open_date - Hardcoded -#fill_in close_date - Hardcoded - click_button "Update poll" - expect(page).to have_content "Poll updated successfully" + fill_in "poll_name", with: "Next Poll" + click_button "Update poll" + + expect(page).to have_content "Poll updated successfully" expect(page).to have_content "Next Poll" end From 042cb14dbdbf198d65e825d9c0310d41f07a795a Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:53:46 +0200 Subject: [PATCH 024/523] moves poll spec to poll folder --- spec/models/{ => poll}/poll_spec.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/models/{ => poll}/poll_spec.rb (100%) diff --git a/spec/models/poll_spec.rb b/spec/models/poll/poll_spec.rb similarity index 100% rename from spec/models/poll_spec.rb rename to spec/models/poll/poll_spec.rb From f3ad806c8b1433eda70c5076f8cea89f99e20c44 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:54:29 +0200 Subject: [PATCH 025/523] updates dev seeds with booths --- db/dev_seeds.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index beb1d815f..2fe812ea5 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -341,4 +341,8 @@ puts "Creating polls" 3.times.each_with_index do |i| Poll.create(name: "Poll #{i}") +end + +10.times.each_with_index do |i| + Poll::Booth.create(name: "Booth #{i}", poll: Poll.all.sample) end \ No newline at end of file From 7db3683c27f1b6f9a56a2b1429463fca80d98b64 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:55:11 +0200 Subject: [PATCH 026/523] adds consistency to syntax --- app/views/admin/poll/polls/index.html.erb | 2 +- config/routes.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 2954e44b8..b4c18d21b 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -4,7 +4,7 @@ new_admin_poll_path, class: "button success float-right" %> -<% if Poll.any? %> +<% if @polls.any? %> diff --git a/config/routes.rb b/config/routes.rb index 070823d63..f682ab529 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -177,7 +177,7 @@ Rails.application.routes.draw do get :search, on: :collection end - scope module: 'poll' do + scope module: :poll do resources :officers do get :search, on: :collection end From 2c3127b6bd74916420cb70e30f39b3e0bf879a9c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:56:19 +0200 Subject: [PATCH 027/523] adds booth backend for index, show, create and edit actions --- .../admin/poll/booths_controller.rb | 31 +++- app/models/abilities/administrator.rb | 5 +- app/models/poll/booth.rb | 2 + app/views/admin/poll/booths/_form.html.erb | 20 +++ app/views/admin/poll/booths/edit.html.erb | 29 +--- app/views/admin/poll/booths/index.html.erb | 49 +++--- app/views/admin/poll/booths/new.html.erb | 29 +--- app/views/admin/poll/booths/show.html.erb | 13 +- app/views/admin/poll/polls/show.html.erb | 4 +- config/locales/admin.en.yml | 4 +- config/locales/responders.en.yml | 2 + config/locales/responders.es.yml | 3 + .../20160926090107_add_location_to_booths.rb | 5 + db/schema.rb | 11 +- spec/factories.rb | 1 + spec/features/admin/poll/booths_spec.rb | 146 ++++++++++++++++++ spec/models/abilities/administrator_spec.rb | 3 + spec/models/poll/booth_spec.rb | 16 ++ 18 files changed, 288 insertions(+), 85 deletions(-) create mode 100644 app/views/admin/poll/booths/_form.html.erb create mode 100644 db/migrate/20160926090107_add_location_to_booths.rb create mode 100644 spec/features/admin/poll/booths_spec.rb create mode 100644 spec/models/poll/booth_spec.rb diff --git a/app/controllers/admin/poll/booths_controller.rb b/app/controllers/admin/poll/booths_controller.rb index 9b1e62f8f..95057ce2f 100644 --- a/app/controllers/admin/poll/booths_controller.rb +++ b/app/controllers/admin/poll/booths_controller.rb @@ -1,5 +1,8 @@ class Admin::Poll::BoothsController < Admin::BaseController - skip_authorization_check + load_and_authorize_resource :poll + load_and_authorize_resource class: 'Poll::Booth', through: :poll + + before_action :load_polls, only: :index def index end @@ -10,7 +13,33 @@ class Admin::Poll::BoothsController < Admin::BaseController def new end + def create + if @booth.save + redirect_to admin_poll_booth_path(@poll, @booth), notice: t("flash.actions.create.poll_booth") + else + render :new + end + end + def edit end + def update + if @booth.update(booth_params) + redirect_to admin_poll_booth_path(@poll, @booth), notice: t("flash.actions.update.poll_booth") + else + render :edit + end + end + + private + + def booth_params + params.require(:poll_booth).permit(:name, :location) + end + + def load_polls + @polls = Poll.all + end + end \ No newline at end of file diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index bd74e1be9..a0e040ab3 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -40,12 +40,13 @@ module Abilities can [:search, :create, :index, :destroy], ::Manager can [:search, :create, :index, :destroy], ::Poll::Officer - can [:manage], Poll - can :manage, Annotation can [:read, :update, :destroy, :summary], SpendingProposal can [:search, :edit, :update, :create, :index, :destroy], Banner + + can [:manage], Poll + can [:manage], Poll::Booth end end end diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index a05f3d547..eb7d81b8c 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -2,5 +2,7 @@ class Poll class Booth < ActiveRecord::Base belongs_to :poll has_many :voters + + validates :name, presence: true end end \ No newline at end of file diff --git a/app/views/admin/poll/booths/_form.html.erb b/app/views/admin/poll/booths/_form.html.erb new file mode 100644 index 000000000..31d60c0f0 --- /dev/null +++ b/app/views/admin/poll/booths/_form.html.erb @@ -0,0 +1,20 @@ +
    +
    + <%= f.text_field :name, + placeholder: t('admin.booths.new.name'), + label: t("admin.booths.new.name") %> +
    + +
    + <%= f.text_field :location, + placeholder: t("admin.booths.new.location"), + label: t("admin.booths.new.location") %> +
    +
    + +
    +
    + <%= f.submit t("admin.booths.#{admin_submit_action(@booth)}.submit_button"), + class: "button success expanded" %> +
    +
    \ No newline at end of file diff --git a/app/views/admin/poll/booths/edit.html.erb b/app/views/admin/poll/booths/edit.html.erb index e48db9cdd..23d825b91 100644 --- a/app/views/admin/poll/booths/edit.html.erb +++ b/app/views/admin/poll/booths/edit.html.erb @@ -1,28 +1,7 @@ <%= render 'shared/back_link' %> -

    <%= t("admin.booths.edit.title") %>: <%= t("admin.booths.edit.subtitle") %>

    +

    <%= t("admin.booths.edit.title", poll: @poll.name) %>: <%= t("admin.booths.edit.subtitle") %>

    -
    -
    -
    - - -
    - -
    - - -
    - -
    - - "> -
    -
    - -
    -
    - -
    -
    - +<%= form_for @booth, url: admin_poll_booth_path(@poll, @booth) do |f| %> + <%= render "form", f: f %> +<% end %> diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 918479f38..b3733670d 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -1,22 +1,27 @@

    <%= t("admin.booths.index.title") %>

    -
    -
    - -
    - - -

    <%= t("admin.booths.index.title_list") %>

    - - -
    - <%= t("admin.booths.index.no_booths") %> +
    + <%= form_tag '', method: :get do %> + <%= select_tag "poll_id", + options_for_select(@polls.collect {|poll| + [poll.name, admin_poll_booths_path(poll)] + }), + prompt: t("admin.booths.index.select_poll"), + class: "js-location-changer" %> + <% end %>
    - -<%= link_to t("admin.booths.index.add_booth"), new_admin_poll_booth_path, class: "button success" %> +

    <%= t("admin.booths.index.title_list", poll: @poll.name) %>

    + +<% if @booths.empty? %> +
    + <%= t("admin.booths.index.no_booths") %> +
    +<% end %> + +<%= link_to t("admin.booths.index.add_booth"), + new_admin_poll_booth_path, + class: "button success" %>
    <%= t("admin.polls.index.name") %>
    @@ -26,23 +31,25 @@ - - + <% @booths.each do |booth| %> + - + <% end %>
     
    - <%= link_to "Urna Moncloa (REFNUM)", "booths/1" %> + <%= link_to booth.name, admin_poll_booth_path(@poll, booth) %> - C/ Isaac Peral, 25. 28003, Madrid + <%= booth.location %> N <%= t("admin.booths.index.officers") %> - <%= link_to t("admin.actions.edit"), "booths/1/edit", class: "button hollow" %> + <%= link_to t("admin.actions.edit"), + edit_admin_poll_booth_path(@poll, booth), + class: "button hollow" %>
    diff --git a/app/views/admin/poll/booths/new.html.erb b/app/views/admin/poll/booths/new.html.erb index e83d2f47c..cffcfab72 100644 --- a/app/views/admin/poll/booths/new.html.erb +++ b/app/views/admin/poll/booths/new.html.erb @@ -1,28 +1,7 @@ <%= render 'shared/back_link' %> -

    <%= t("admin.booths.new.title") %>: <%= t("admin.booths.new.subtitle") %>

    +

    <%= t("admin.booths.new.title", poll: @poll.name) %>: <%= t("admin.booths.new.subtitle") %>

    -
    -
    -
    - - -
    - -
    - - -
    - -
    - - "> -
    -
    - -
    -
    - -
    -
    -
    +<%= form_for @booth, url: admin_poll_booths_path(@poll) do |f| %> + <%= render "form", f: f %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 34e1a4465..55f7d5504 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -1,10 +1,17 @@ <%= render 'shared/back_link' %>
    -

    Urna Moncloa (REFNUM)

    -<%= link_to t("admin.actions.edit"), "1/edit", class: "button hollow float-right" %> +

    + <%= @booth.name %> +

    +<%= link_to t("admin.actions.edit"), + edit_admin_poll_booth_path(@poll, @booth), + class: "button hollow float-right" %> -

    <%= t("admin.booths.show.location") %>: C/ Isaac Peral, 25. 28003, Madrid

    +

    + <%= t("admin.booths.show.location") %>: + <%= @booth.location %> +

    <%= t("admin.booths.show.officers_list") %>

    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 1b0d1e198..17248d4b9 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -5,7 +5,9 @@ <%= @poll.name %> -<%= link_to t("admin.actions.edit"), edit_admin_poll_path(@poll), class: "button hollow float-right" %> +<%= link_to t("admin.actions.edit"), + edit_admin_poll_path(@poll), + class: "button hollow float-right" %>

    (REFNUM)

    Próximamente (15/12/2016 - 15/02/2017)

    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index bb8093b03..db4cf34ca 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -174,7 +174,7 @@ en: close_date: "Close date" submit_button: "Update poll" show: - no_booths: "There is no booths in this poll." + no_booths: "There are no booths in this poll." add_booth: "Add booth" booths_title: "List of booths" name: "Name" @@ -184,7 +184,7 @@ en: title: "List of booths" select_poll: "Select a poll" title_list: "List of booths of poll %{poll}" - no_booths: "There is no booths in this poll." + no_booths: "There are no booths in this poll." add_booth: "Add booth" name: "Name" location: "Location" diff --git a/config/locales/responders.en.yml b/config/locales/responders.en.yml index 422a59e0c..68d77b0d2 100755 --- a/config/locales/responders.en.yml +++ b/config/locales/responders.en.yml @@ -7,6 +7,7 @@ en: debate: "Debate created successfully." direct_message: "You message has been sent successfully." poll: "Poll created successfully." + poll_booth: "Booth created successfully." proposal: "Proposal created successfully." proposal_notification: "Your message has been sent correctly." spending_proposal: "Spending proposal created successfully. You can access it from %{activity}" @@ -16,6 +17,7 @@ en: notice: "%{resource_name} updated successfully." debate: "Debate updated successfully." poll: "Poll updated successfully." + poll_booth: "Booth updated successfully." proposal: "Proposal updated successfully." spending_proposal: "Investment project updated succesfully." destroy: diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index c9292b187..105b00903 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -7,6 +7,7 @@ es: debate: "Debate creado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente." poll: "Votación presencial creada correctamente." + poll_booth: "Urna creada correctamente." proposal: "Propuesta creada correctamente." proposal_notification: "Tu message ha sido enviado correctamente." spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}" @@ -16,6 +17,8 @@ es: notice: "%{resource_name} actualizado correctamente." debate: "Debate actualizado correctamente." proposal: "Propuesta actualizada correctamente." + poll: "Votación presencial actualizada correctamente." + poll_booth: "Urna actualizada correctamente." spending_proposal: "Propuesta de inversión actualizada correctamente." destroy: spending_proposal: "Propuesta de inversión eliminada." \ No newline at end of file diff --git a/db/migrate/20160926090107_add_location_to_booths.rb b/db/migrate/20160926090107_add_location_to_booths.rb new file mode 100644 index 000000000..146f55d41 --- /dev/null +++ b/db/migrate/20160926090107_add_location_to_booths.rb @@ -0,0 +1,5 @@ +class AddLocationToBooths < ActiveRecord::Migration + def change + add_column :poll_booths, :location, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 205fc5f21..493dfbe3a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160914172535) do +ActiveRecord::Schema.define(version: 20160926090107) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -273,6 +273,11 @@ ActiveRecord::Schema.define(version: 20160914172535) do create_table "poll_booths", force: :cascade do |t| t.string "name" t.integer "poll_id" + t.string "location" + end + + create_table "poll_officers", force: :cascade do |t| + t.integer "user_id" end create_table "poll_voters", force: :cascade do |t| @@ -281,10 +286,6 @@ ActiveRecord::Schema.define(version: 20160914172535) do t.string "document_type" end - create_table "poll_officers", force: :cascade do |t| - t.integer "user_id" - end - create_table "polls", force: :cascade do |t| t.string "name" end diff --git a/spec/factories.rb b/spec/factories.rb index ac7bb379b..f7e09b7e8 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -269,6 +269,7 @@ FactoryGirl.define do factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } + sequence(:location) { |n| "Street #{n}" } poll end diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb new file mode 100644 index 000000000..ad46c67fb --- /dev/null +++ b/spec/features/admin/poll/booths_spec.rb @@ -0,0 +1,146 @@ +require 'rails_helper' + +feature 'Admin booths' do + + let!(:poll) { create(:poll) } + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'Index empty' do + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + expect(page).to have_content "There are no booths in this poll" + end + + scenario 'No link to booths when no polls' do + Poll.destroy_all + + visit admin_root_path + + within('#side_menu') do + expect(page).to_not have_link "Booths" + end + end + + scenario 'Index' do + 3.times { create(:poll_booth, poll: poll) } + + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + expect(page).to have_css ".booth", count: 3 + + booths = Poll::Booth.all + booths.each do |booth| + within("#booth_#{booth.id}") do + expect(page).to have_content booth.name + expect(page).to have_content booth.location + end + end + expect(page).to_not have_content "There are no booths" + end + + scenario "Index default to last poll" do + poll1 = create(:poll) + poll2 = create(:poll) + + booth1 = create(:poll_booth, poll: poll1) + booth2 = create(:poll_booth, poll: poll2) + + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + expect(page).to have_css ".booth", count: 1 + expect(page).to have_content booth2.name + expect(page).to_not have_content booth1.name + end + + scenario "Index select poll", :js do + poll1 = create(:poll) + poll2 = create(:poll) + + booth1 = create(:poll_booth, poll: poll1) + booth2 = create(:poll_booth, poll: poll2) + + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + select poll1.name, from: "poll_id" + + expect(page).to have_content "List of booths of poll #{poll1.name}" + expect(page).to have_css ".booth", count: 1 + expect(page).to have_content booth1.name + expect(page).to_not have_content booth2.name + end + + scenario 'Show' do + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booths_path(poll) + click_link booth.name + + expect(page).to have_content booth.name + expect(page).to have_content booth.location + end + + scenario "Create" do + visit admin_poll_booths_path(poll) + click_link "Add booth" + + expect(page).to have_content "Poll #{poll.name}" + + fill_in "poll_booth_name", with: "Upcoming booth" + fill_in "poll_booth_location", with: "39th Street, number 2, ground floor" + click_button "Create booth" + + expect(page).to have_content "Booth created successfully" + expect(page).to have_content "Upcoming booth" + expect(page).to have_content "39th Street, number 2, ground floor" + end + + scenario "Edit" do + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booths_path(poll) + + click_link "Edit" + + expect(page).to have_content "Poll #{poll.name}" + + fill_in "poll_booth_name", with: "Next booth" + fill_in "poll_booth_location", with: "40th Street, number 1, firts floor" + click_button "Update booth" + + expect(page).to have_content "Booth updated successfully" + expect(page).to have_content "Next booth" + expect(page).to have_content "40th Street, number 1, firts floor" + end + + scenario 'Edit from index' do + booth = create(:poll_booth, poll: poll) + visit admin_poll_booths_path(poll) + + within("#booth_#{booth.id}") do + click_link "Edit" + end + + expect(current_path).to eq(edit_admin_poll_booth_path(poll, booth)) + end + +end \ No newline at end of file diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb index f9ed7a0c5..04fd199f0 100644 --- a/spec/models/abilities/administrator_spec.rb +++ b/spec/models/abilities/administrator_spec.rb @@ -56,4 +56,7 @@ describe "Abilities::Administrator" do it { should be_able_to(:update, SpendingProposal) } it { should be_able_to(:valuate, SpendingProposal) } it { should be_able_to(:destroy, SpendingProposal) } + + it { should be_able_to(:manage, Poll) } + it { should be_able_to(:manage, Poll::Booth) } end diff --git a/spec/models/poll/booth_spec.rb b/spec/models/poll/booth_spec.rb new file mode 100644 index 000000000..2fabb9c12 --- /dev/null +++ b/spec/models/poll/booth_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +describe :booth do + + let(:booth) { build(:poll_booth) } + + it "should be valid" do + expect(booth).to be_valid + end + + it "should not be valid without a name" do + booth.name = nil + expect(booth).to_not be_valid + end + +end \ No newline at end of file From a8ea86fae1f84f7ff39a542146b3609ec8eb6e7f Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:56:48 +0200 Subject: [PATCH 028/523] removes unused attributes from poll show --- app/views/admin/poll/polls/_poll.html.erb | 4 ---- app/views/admin/poll/polls/show.html.erb | 2 -- 2 files changed, 6 deletions(-) diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index 4128ad222..d90fed14a 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -4,10 +4,6 @@ <%= link_to poll.name, admin_poll_path(poll) %>
    - - Próximamente -
    (15/12/2016 - 15/02/2017) - <%= link_to t("admin.actions.edit"), edit_admin_poll_path(poll), diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 17248d4b9..8a02ebfd7 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -9,8 +9,6 @@ edit_admin_poll_path(@poll), class: "button hollow float-right" %> -

    (REFNUM)

    -

    Próximamente (15/12/2016 - 15/02/2017)

    <%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> From e97e7e20dc27339ea932ff148ce59022ab72ca44 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 12:01:58 +0200 Subject: [PATCH 029/523] maintains poll date and status in index for demo --- app/views/admin/poll/polls/_poll.html.erb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index d90fed14a..4128ad222 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -4,6 +4,10 @@ <%= link_to poll.name, admin_poll_path(poll) %> + + Próximamente +
    (15/12/2016 - 15/02/2017) + <%= link_to t("admin.actions.edit"), edit_admin_poll_path(poll), From 6387d281578bd00cd7b9f10a5e10ec3cd8379910 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 12:34:24 +0200 Subject: [PATCH 030/523] adds booth info to poll show --- app/views/admin/poll/booths/_booth.html.erb | 18 +++++++ app/views/admin/poll/booths/index.html.erb | 21 +------- app/views/admin/poll/polls/show.html.erb | 55 +++++++++------------ config/locales/admin.en.yml | 1 + config/locales/admin.es.yml | 1 + spec/features/admin/poll/polls_spec.rb | 44 ++++++++++++++++- 6 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 app/views/admin/poll/booths/_booth.html.erb diff --git a/app/views/admin/poll/booths/_booth.html.erb b/app/views/admin/poll/booths/_booth.html.erb new file mode 100644 index 000000000..ff1683867 --- /dev/null +++ b/app/views/admin/poll/booths/_booth.html.erb @@ -0,0 +1,18 @@ + + + + <%= link_to booth.name, admin_poll_booth_path(@poll, booth) %> + + + + <%= booth.location %> + + + N <%= t("admin.booths.index.officers") %> + + + <%= link_to t("admin.actions.edit"), + edit_admin_poll_booth_path(@poll, booth), + class: "button hollow" %> + + \ No newline at end of file diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index b3733670d..d2a9a7e5a 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -20,7 +20,7 @@ <% end %> <%= link_to t("admin.booths.index.add_booth"), - new_admin_poll_booth_path, + new_admin_poll_booth_path(@poll), class: "button success" %> @@ -32,24 +32,7 @@ <% @booths.each do |booth| %> - - - - - - + <%= render partial: "booth", locals: { booth: booth } %> <% end %>
    - - <%= link_to booth.name, admin_poll_booth_path(@poll, booth) %> - - - <%= booth.location %> - - N <%= t("admin.booths.index.officers") %> - - <%= link_to t("admin.actions.edit"), - edit_admin_poll_booth_path(@poll, booth), - class: "button hollow" %> -
    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 8a02ebfd7..bed01af41 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -9,37 +9,28 @@ edit_admin_poll_path(@poll), class: "button hollow float-right" %> -<%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> +<%= link_to t("admin.polls.show.add_booth"), + new_admin_poll_booth_path(@poll), + class: "button success" %> - -
    - <%= t("admin.polls.show.no_booths") %> -
    - +<% if @poll.booths.empty? %> +
    + <%= t("admin.polls.show.no_booths") %> +
    +<% else %> +

    <%= t("admin.polls.show.booths_title") %>

    -

    <%= t("admin.polls.show.booths_title") %>

    - - - - - - - - - <%= @poll.booths.each do |booth| %> - - - - - - <% end %> - -
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> 
    - - <%= link_to "Urna Moncloa (REFNUM)", "#" %> - - - C/ Isaac Peral, 25. 28003, Madrid - - <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> -
    + + + + + + + + + <% @poll.booths.each do |booth| %> + <%= render partial: "admin/poll/booths/booth", locals: { booth: booth } %> + <% end %> + +
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %><%= t("admin.polls.show.officers") %> 
    +<% end %> \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index db4cf34ca..ef294262d 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -179,6 +179,7 @@ en: booths_title: "List of booths" name: "Name" location: "Location" + officers: "Officers" booths: index: title: "List of booths" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 6023da712..48dfe2959 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -179,6 +179,7 @@ es: booths_title: "Listado de urnas" name: "Nombre" location: "Ubicación" + officers: "Presidentes de mesa" booths: index: title: "Lista de urnas" diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index bab7b5847..80f875567 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -27,7 +27,8 @@ feature 'Admin polls' do expect(page).to have_css ".poll", count: 3 - Poll.all.each do |poll| + polls = Poll.all + polls.each do |poll| within("#poll_#{poll.id}") do expect(page).to have_content poll.name end @@ -79,4 +80,45 @@ feature 'Admin polls' do expect(current_path).to eq(edit_admin_poll_path(poll)) end + context "Booths" do + + context "Poll show" do + + scenario "No booths" do + poll = create(:poll) + visit admin_poll_path(poll) + + expect(page).to have_content "There are no booths in this poll." + end + + scenario "Booth list" do + poll = create(:poll) + 3.times { create(:poll_booth, poll: poll) } + + visit admin_poll_path(poll) + + expect(page).to have_css ".booth", count: 3 + + booths = Poll::Booth.all + booths.each do |booth| + within("#booth_#{booth.id}") do + expect(page).to have_content booth.name + expect(page).to have_content booth.location + end + end + expect(page).to_not have_content "There are no booths" + end + + scenario "Add booth" do + poll = create(:poll) + visit admin_poll_path(poll) + + click_link "Add booth" + + expect(current_path).to eq(new_admin_poll_booth_path(poll)) + expect(page).to have_content poll.name + end + end + end + end \ No newline at end of file From 527b734e0ebae60f30c76e03e7a5082eacdad0a4 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 18:39:01 +0200 Subject: [PATCH 031/523] assigns officers to booths --- .../admin/poll/booths_controller.rb | 3 +- app/helpers/officers_helper.rb | 7 + app/models/poll/booth.rb | 2 + app/models/poll/officing_booth.rb | 6 + app/views/admin/poll/booths/show.html.erb | 40 +++--- config/locales/admin.en.yml | 2 +- .../20160928113143_create_officing_booths.rb | 9 ++ db/schema.rb | 9 +- spec/factories.rb | 5 + spec/features/admin/poll/officers_spec.rb | 129 +++++++++++++++++- 10 files changed, 185 insertions(+), 27 deletions(-) create mode 100644 app/helpers/officers_helper.rb create mode 100644 app/models/poll/officing_booth.rb create mode 100644 db/migrate/20160928113143_create_officing_booths.rb diff --git a/app/controllers/admin/poll/booths_controller.rb b/app/controllers/admin/poll/booths_controller.rb index 95057ce2f..1d05ddab5 100644 --- a/app/controllers/admin/poll/booths_controller.rb +++ b/app/controllers/admin/poll/booths_controller.rb @@ -8,6 +8,7 @@ class Admin::Poll::BoothsController < Admin::BaseController end def show + @officers = Poll::Officer.all end def new @@ -35,7 +36,7 @@ class Admin::Poll::BoothsController < Admin::BaseController private def booth_params - params.require(:poll_booth).permit(:name, :location) + params.require(:poll_booth).permit(:name, :location, officer_ids: []) end def load_polls diff --git a/app/helpers/officers_helper.rb b/app/helpers/officers_helper.rb new file mode 100644 index 000000000..f29bcf728 --- /dev/null +++ b/app/helpers/officers_helper.rb @@ -0,0 +1,7 @@ +module OfficersHelper + + def officer_label(officer) + truncate([officer.name, officer.email].compact.join(' - '), length: 100) + end + +end \ No newline at end of file diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index eb7d81b8c..74c4c3edb 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -2,6 +2,8 @@ class Poll class Booth < ActiveRecord::Base belongs_to :poll has_many :voters + has_many :officing_booths, dependent: :destroy + has_many :officers, through: :officing_booths validates :name, presence: true end diff --git a/app/models/poll/officing_booth.rb b/app/models/poll/officing_booth.rb new file mode 100644 index 000000000..f0a64721a --- /dev/null +++ b/app/models/poll/officing_booth.rb @@ -0,0 +1,6 @@ +class Poll + class OfficingBooth < ActiveRecord::Base + belongs_to :officer + belongs_to :booth + end +end diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 55f7d5504..cce704d2c 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -15,34 +15,32 @@

    <%= t("admin.booths.show.officers_list") %>

    - -
    - <%= t("admin.booths.show.no_officers") %> -
    - - -<%= link_to t("admin.booths.show.assign_officer"), "#", class: "button success" %> +<% if @booth.officers.empty? %> +
    + <%= t("admin.booths.show.no_officers") %> +
    +<% end %>
    - - <%# f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %> + <%= form_for @booth, url: admin_poll_booth_path(@poll, @booth) do |f| %> - <%# f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %> - <%# b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %> - <%# end %> + <%= f.label :officer_ids, t("admin.spending_proposals.edit.assigned_valuators") %> + <%= f.collection_check_boxes :officer_ids, @officers, :id, :email do |b| %> + <% b.label { b.check_box + truncate(officer_label(b.object), length: 60) } %> + <% end %> + + <%= f.submit t("admin.booths.show.assign_officer"), class: "button success" %> + <% end %>
    - - <%# @officers.each do |officer| %> - +
    + <% @booth.officers.each do |officer| %> + - <%# end %> + <% end %>
    - <%# officer.name %> - Admin + <%= officer.name %> - admin@consul.dev - <%# officer.email %> + <%= officer.email %> <%= link_to t('admin.poll_officers.officer.delete'), "#", class: "button hollow alert" %> @@ -53,5 +51,5 @@ %>
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index ef294262d..c4a94a86e 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -208,7 +208,7 @@ en: location: "Location" assign_officer: "Assign officer" officers_list: "List of officers" - no_officers: "There is no officers in this booth." + no_officers: "There are no officers assigned to this booth" officials: edit: destroy: Remove 'Official' status diff --git a/db/migrate/20160928113143_create_officing_booths.rb b/db/migrate/20160928113143_create_officing_booths.rb new file mode 100644 index 000000000..00483fe00 --- /dev/null +++ b/db/migrate/20160928113143_create_officing_booths.rb @@ -0,0 +1,9 @@ +class CreateOfficingBooths < ActiveRecord::Migration + def change + create_table :poll_officing_booths do |t| + t.belongs_to :officer + t.belongs_to :booth + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 493dfbe3a..98be0a56f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160926090107) do +ActiveRecord::Schema.define(version: 20160928113143) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -280,6 +280,13 @@ ActiveRecord::Schema.define(version: 20160926090107) do t.integer "user_id" end + create_table "poll_officing_booths", force: :cascade do |t| + t.integer "officer_id" + t.integer "booth_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "poll_voters", force: :cascade do |t| t.integer "booth_id" t.string "document_number" diff --git a/spec/factories.rb b/spec/factories.rb index f7e09b7e8..92fefba11 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -267,6 +267,11 @@ FactoryGirl.define do user end + factory :officing_booth, class: 'Poll::OfficingBooth' do + association :officer, factory: :poll_officer + association :booth, factory: :poll_booth + end + factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } sequence(:location) { |n| "Street #{n}" } diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb index ed9ec545d..981b17f13 100644 --- a/spec/features/admin/poll/officers_spec.rb +++ b/spec/features/admin/poll/officers_spec.rb @@ -1,12 +1,13 @@ require 'rails_helper' feature 'Admin poll officers' do + background do @admin = create(:administrator) @user = create(:user, username: 'Pedro Jose Garcia') @officer = create(:poll_officer) login_as(@admin.user) - visit admin_poll_officers_path + visit admin_officers_path end scenario 'Index' do @@ -15,7 +16,7 @@ feature 'Admin poll officers' do expect(page).to_not have_content @user.name end - scenario 'Create poll officer', :js do + scenario 'Create', :js do fill_in 'email', with: @user.email click_button 'Search' @@ -26,11 +27,133 @@ feature 'Admin poll officers' do end end - scenario 'Delete poll officer' do + scenario 'Delete' do click_link 'Delete' within("#officers") do expect(page).to_not have_content @officer.name end end + + context "Booth" do + + scenario 'No officers assigned to booth' do + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booth_path(poll, booth) + + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 0 + end + + expect(page).to have_content "There are no officers assigned to this booth" + end + + scenario "Assigned to booth" do + john = create(:poll_officer) + isabel = create(:poll_officer) + eve = create(:poll_officer) + + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + officing_booth1 = create(:officing_booth, officer: john, booth: booth) + officing_booth2 = create(:officing_booth, officer: isabel, booth: booth) + + visit admin_poll_booth_path(poll, booth) + + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 2 + expect(page).to have_content john.name + expect(page).to have_content isabel.name + + expect(page).to_not have_content eve.name + end + + expect(page).to_not have_content "There are no officers assigned to this booth" + end + + scenario 'Assign to booth' do + john = create(:poll_officer) + isabel = create(:poll_officer) + + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booth_path(poll, booth) + + check "#{john.name} - #{john.email}" + click_button "Assign officer" + + expect(page).to have_content "Booth updated successfully." + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content john.name + end + end + + scenario "Unassign from booth" do + john = create(:poll_officer) + isabel = create(:poll_officer) + + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + officing_booth = create(:officing_booth, officer: john, booth: booth) + officing_booth = create(:officing_booth, officer: isabel, booth: booth) + + visit admin_poll_booth_path(poll, booth) + + uncheck "#{john.name} - #{john.email}" + click_button "Assign officer" + + expect(page).to have_content "Booth updated successfully." + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content isabel.name + + expect(page).to_not have_content john.name + end + end + + scenario "Assigned multiple officers to different booths" do + john = create(:poll_officer) + isabel = create(:poll_officer) + eve = create(:poll_officer) + peter = create(:poll_officer) + + poll1 = create(:poll) + poll2 = create(:poll) + + booth1 = create(:poll_booth, poll: poll1) + booth2 = create(:poll_booth, poll: poll1) + booth3 = create(:poll_booth, poll: poll2) + + officing_booth = create(:officing_booth, officer: john, booth: booth1) + officing_booth = create(:officing_booth, officer: isabel, booth: booth1) + officing_booth = create(:officing_booth, officer: eve, booth: booth2) + officing_booth = create(:officing_booth, officer: peter, booth: booth3) + + visit admin_poll_booth_path(poll1, booth1) + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 2 + expect(page).to have_content john.name + expect(page).to have_content isabel.name + end + + visit admin_poll_booth_path(poll1, booth2) + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content eve.name + end + + visit admin_poll_booth_path(poll2, booth3) + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content peter.name + end + end + end + end \ No newline at end of file From 1c75dca13a09ce93c9a71b7bde132c2b7a6a6832 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 14 Oct 2016 19:00:58 +0200 Subject: [PATCH 032/523] adds styles for offering voters views --- app/views/officing/dashboard/index.html.erb | 1 - app/views/officing/voters/new.html.erb | 21 +++++++++++++++- app/views/officing/voters/show.html.erb | 26 +++++++++++++++++++- config/locales/officing.en.yml | 18 ++++++++++++-- config/locales/officing.es.yml | 27 +++++++++++++++++++-- 5 files changed, 86 insertions(+), 7 deletions(-) diff --git a/app/views/officing/dashboard/index.html.erb b/app/views/officing/dashboard/index.html.erb index cf014d719..861a39b1a 100644 --- a/app/views/officing/dashboard/index.html.erb +++ b/app/views/officing/dashboard/index.html.erb @@ -2,5 +2,4 @@

    <%= t("officing.dashboard.index.title") %>

    <%= t("officing.dashboard.index.info") %>

    - diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 0fb4c6bc3..37edfd788 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -1 +1,20 @@ -voters new +

    <%= t("officing.voters.new.title") %>

    + +
    +
    +
    + + + + + + "> + + " class="button"> +
    +
    +
    diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb index fd8c83123..3de9d9651 100644 --- a/app/views/officing/voters/show.html.erb +++ b/app/views/officing/voters/show.html.erb @@ -1 +1,25 @@ -voters show \ No newline at end of file +

    <%= t("officing.voters.show.title") %>

    + + + +
    + <%= t("officing.voters.show.error_verifying_census") %> +
    + + + +
    + <%= t("officing.voters.show.error_already_voted") %> +
    + + + +
    + <%= t("officing.voters.show.success") %> +
    + +
    +
    + " class="button success expanded"> +
    +
    diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index 532d18498..c8989dfc6 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -6,5 +6,19 @@ en: title: Poll officing info: Here you can validate user documents and store voting results menu: - voters: Validate citizen document - results: Store voting results \ No newline at end of file + voters: Validate document + results: Store results + voters: + new: + title: Validate document + document_number: Document number + document_type: + passport: Passport + residence_card: Residence card + spanish_id: DNI + document_type_label: Document type + submit: Validate document + show: + title: Validate document + error_verifying_census: "The Census was unable to verify your information." + error_already_voted: "La persona asociada al documento ya ha participado en la votación." \ No newline at end of file diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index baa60b106..8ab0dc384 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -6,5 +6,28 @@ es: title: Presidir mesa de votaciones info: Aquí puedes validar documentos de ciudadanos y guardar los resultados de las urnas menu: - voters: Validar documento de identidad - results: Guardar resultados de la votación \ No newline at end of file + voters: Validar documento + results: Guardar resultados + voters: + new: + title: Validar documento + document_number: Número de documento + document_type: + passport: Pasaporte + residence_card: Tarjeta de residencia + spanish_id: DNI + document_type_label: Tipo de documento + submit: Validar documento + show: + title: Validar documento + error_verifying_census: "El Padrón no pudo verificar tu información." + error_already_voted: "La persona asociada al documento ya ha participado en la votación." + success: "La persona asociada al documento puede participar en la votación." + submit: Validar voto + results: + index: + title: "Resultados de la votación" + new: + title: "Añadir resultados" + show: + title: "Resultados" \ No newline at end of file From 5a78e51de25ed4f793d98b35e3c3e0276c328e91 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Oct 2016 16:42:50 +0200 Subject: [PATCH 033/523] adds styles to officing voters views --- app/assets/stylesheets/admin.scss | 4 ++ app/views/officing/_menu.html.erb | 2 +- app/views/officing/results/index.html.erb | 55 ++++++++++++++++++++++- app/views/officing/results/new.html.erb | 39 +++++++++++++++- app/views/officing/results/show.html.erb | 51 ++++++++++++++++++++- app/views/officing/voters/new.html.erb | 2 +- app/views/officing/voters/show.html.erb | 7 ++- config/locales/officing.en.yml | 24 +++++++++- config/locales/officing.es.yml | 19 ++++++-- 9 files changed, 191 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index cd8241fca..bbb9fee4f 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -42,6 +42,10 @@ body.admin { th { text-align: left; + + &.text-center { + text-align: center; + } } tr { diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb index 81734d99f..f051b5940 100644 --- a/app/views/officing/_menu.html.erb +++ b/app/views/officing/_menu.html.erb @@ -14,5 +14,5 @@ <%= t("officing.menu.results") %> <% end %>
  • - + diff --git a/app/views/officing/results/index.html.erb b/app/views/officing/results/index.html.erb index 8e9faa1ab..8e50de625 100644 --- a/app/views/officing/results/index.html.erb +++ b/app/views/officing/results/index.html.erb @@ -1 +1,54 @@ -results index \ No newline at end of file +

    <%= t("officing.results.index.title") %>

    + +
    +
    + +
    + +
    + +
    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%= t("officing.shared.booth") %><%= t("officing.shared.date") %><%= t("officing.shared.officer") %><%= t("officing.shared.votes_number") %>
    <%= link_to "Urna Moncloa (1)", officing_poll_result_path(Poll.last, 1) %>14/10/2016Officer Name (officer@email.com)124
    <%= link_to "Urna Cahamartín (6)", officing_poll_result_path(Poll.last, 1) %>17/10/2016Other Officer (otherofficer@email.com)350
    <%= t("officing.results.index.total_votes") %>474
    diff --git a/app/views/officing/results/new.html.erb b/app/views/officing/results/new.html.erb index bb40dff9e..178efbadd 100644 --- a/app/views/officing/results/new.html.erb +++ b/app/views/officing/results/new.html.erb @@ -1 +1,38 @@ -results new \ No newline at end of file +

    <%= t("officing.results.new.title") %>

    + +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    +
    + +
    + +
    +
    + + "> +
    +
    + +
    +
    + " class="button expanded"> +
    +
    +
    diff --git a/app/views/officing/results/show.html.erb b/app/views/officing/results/show.html.erb index b3ca8e29c..4c7b88e00 100644 --- a/app/views/officing/results/show.html.erb +++ b/app/views/officing/results/show.html.erb @@ -1 +1,50 @@ -results show \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("officing.results.show.title", booth: "Booth Name (1)") %>

    + +
    +
    + +
    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%= t("officing.shared.date") %><%= t("officing.shared.officer") %><%= t("officing.shared.votes_number") %>
    14/10/2016Officer Name (officer@email.com)124
    17/10/2016Other Officer (otherofficer@email.com)350
    18/10/2016Officer number 3 (officer3@email.com)100
    <%= t("officing.results.index.total_votes") %>574
    diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 37edfd788..2042f7acb 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -1,7 +1,7 @@

    <%= t("officing.voters.new.title") %>

    -
    +
    diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb index 3de9d9651..523e0e0d4 100644 --- a/app/views/officing/voters/show.html.erb +++ b/app/views/officing/voters/show.html.erb @@ -15,7 +15,7 @@
    - <%= t("officing.voters.show.success") %> + <%= t("officing.voters.show.can_participate") %>
    @@ -23,3 +23,8 @@ " class="button success expanded">
    + + +
    + <%= t("officing.voters.show.success") %> +
    \ No newline at end of file diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index c8989dfc6..20cd8fcfc 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -20,5 +20,25 @@ en: submit: Validate document show: title: Validate document - error_verifying_census: "The Census was unable to verify your information." - error_already_voted: "La persona asociada al documento ya ha participado en la votación." \ No newline at end of file + error_verifying_census: "The Census was unable to verify the information of this document." + error_already_voted: "The person associated with the document has already participated in the vote." + can_participate: "The person associated with the document can participate in the vote." + submit: Validate vote + success: "Vote validated correctly." + results: + index: + title: "Vote results" + total_votes: "Total number of votes" + new: + title: Save results + submit: Save + show: + title: "%{booth} results" + shared: + filter_booth: All booths + filter_date: All dates + filter_officer: All officers + booth: Booth + date: Date + officer: Officer + votes_number: Number of votes diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index 8ab0dc384..e187365f1 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -20,14 +20,25 @@ es: submit: Validar documento show: title: Validar documento - error_verifying_census: "El Padrón no pudo verificar tu información." + error_verifying_census: "El Padrón no pudo verificar la información de este documento." error_already_voted: "La persona asociada al documento ya ha participado en la votación." - success: "La persona asociada al documento puede participar en la votación." + can_participate: "La persona asociada al documento puede participar en la votación." submit: Validar voto + success: "Voto validado correctamente." results: index: title: "Resultados de la votación" + total_votes: "Número total de votos" new: - title: "Añadir resultados" + title: Guardar resultados + submit: Guardar show: - title: "Resultados" \ No newline at end of file + title: "Resultados de %{booth}" + shared: + filter_booth: Todas las urnas + filter_date: Todas las fechas + filter_officer: Todos los presidentes de mesa + booth: Urna + date: Fecha + officer: Presidente de mesa + votes_number: Número de votos From e4d8b8732d5ca54756c593f269d6812b778942b9 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Oct 2016 16:43:11 +0200 Subject: [PATCH 034/523] add officing to i18n tasks --- config/i18n-tasks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 250ed18f9..245eebbcf 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -32,6 +32,7 @@ data: - config/locales/devise_views.%{locale}.yml - config/locales/responders.%{locale}.yml - config/locales/kaminari.%{locale}.yml + - config/locales/officing.%{locale}.yml # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom: # `i18n-tasks normalize -p` will force move the keys according to these rules From 32abb1eadd8ee8b00a641e58f7c92e7d188a7331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 19 Oct 2016 13:44:05 +0200 Subject: [PATCH 035/523] removes booths link from admin menu --- app/views/admin/_menu.html.erb | 8 ---- spec/features/admin/poll/booths_spec.rb | 57 +++---------------------- 2 files changed, 5 insertions(+), 60 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 0661a3bb6..11e46814d 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -95,14 +95,6 @@ <% end %> - <% if Poll.any? %> -
  • > - <%= link_to admin_poll_booths_url(Poll.last) do %> - <%= t('admin.menu.booths') %> - <% end %> -
  • - <% end %> -
  • > <%= link_to admin_activity_path do %> <%= t('admin.menu.activity') %> diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb index ad46c67fb..eff653dfe 100644 --- a/spec/features/admin/poll/booths_spec.rb +++ b/spec/features/admin/poll/booths_spec.rb @@ -13,32 +13,24 @@ feature 'Admin booths' do visit admin_root_path within('#side_menu') do - click_link "Booths" + click_link "Polls" end + click_link poll.name + expect(page).to have_content "There are no booths in this poll" end - scenario 'No link to booths when no polls' do - Poll.destroy_all - - visit admin_root_path - - within('#side_menu') do - expect(page).to_not have_link "Booths" - end - end - scenario 'Index' do 3.times { create(:poll_booth, poll: poll) } visit admin_root_path within('#side_menu') do - click_link "Booths" + click_link "Polls" end - expect(page).to have_css ".booth", count: 3 + click_link poll.name booths = Poll::Booth.all booths.each do |booth| @@ -50,45 +42,6 @@ feature 'Admin booths' do expect(page).to_not have_content "There are no booths" end - scenario "Index default to last poll" do - poll1 = create(:poll) - poll2 = create(:poll) - - booth1 = create(:poll_booth, poll: poll1) - booth2 = create(:poll_booth, poll: poll2) - - visit admin_root_path - - within('#side_menu') do - click_link "Booths" - end - - expect(page).to have_css ".booth", count: 1 - expect(page).to have_content booth2.name - expect(page).to_not have_content booth1.name - end - - scenario "Index select poll", :js do - poll1 = create(:poll) - poll2 = create(:poll) - - booth1 = create(:poll_booth, poll: poll1) - booth2 = create(:poll_booth, poll: poll2) - - visit admin_root_path - - within('#side_menu') do - click_link "Booths" - end - - select poll1.name, from: "poll_id" - - expect(page).to have_content "List of booths of poll #{poll1.name}" - expect(page).to have_css ".booth", count: 1 - expect(page).to have_content booth1.name - expect(page).to_not have_content booth2.name - end - scenario 'Show' do booth = create(:poll_booth, poll: poll) From 0d3476524753a881c023b087504f4af8d153b15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 12:31:06 +0200 Subject: [PATCH 036/523] removes unused i18n key --- config/locales/admin.en.yml | 1 - config/locales/admin.es.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index c4a94a86e..6c42ac23e 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -106,7 +106,6 @@ en: valuators: Valuators poll_officers: Poll officers polls: Polls - booths: Booths officials: Officials organizations: Organisations settings: Configuration settings diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 48dfe2959..55991e056 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -106,7 +106,6 @@ es: valuators: Evaluadores poll_officers: Presidentes de mesa polls: Votaciones - booths: Urnas officials: Cargos públicos organizations: Organizaciones settings: Configuración global From 44691a0bd73e30a9657bfbd6b1ca38492d60c3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 16:14:03 +0200 Subject: [PATCH 037/523] adds dates to polls --- db/migrate/20161020112156_add_dates_to_polls.rb | 6 ++++++ db/schema.rb | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20161020112156_add_dates_to_polls.rb diff --git a/db/migrate/20161020112156_add_dates_to_polls.rb b/db/migrate/20161020112156_add_dates_to_polls.rb new file mode 100644 index 000000000..d504930ae --- /dev/null +++ b/db/migrate/20161020112156_add_dates_to_polls.rb @@ -0,0 +1,6 @@ +class AddDatesToPolls < ActiveRecord::Migration + def change + add_column :polls, :starts_at, :datetime + add_column :polls, :ends_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 5d81903a1..d1862bf11 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160928113143) do +ActiveRecord::Schema.define(version: 20161020112156) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -294,7 +294,9 @@ ActiveRecord::Schema.define(version: 20160928113143) do end create_table "polls", force: :cascade do |t| - t.string "name" + t.string "name" + t.datetime "starts_at" + t.datetime "ends_at" end create_table "proposal_notifications", force: :cascade do |t| From 01d337f7e96082f135e807c36dd0b49f92495dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 16:25:02 +0200 Subject: [PATCH 038/523] changes menu name --- config/locales/admin.es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 55991e056..024f6abe2 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -105,7 +105,7 @@ es: moderators: Moderadores valuators: Evaluadores poll_officers: Presidentes de mesa - polls: Votaciones + polls: Votaciones físicas officials: Cargos públicos organizations: Organizaciones settings: Configuración global From d279baa29a0e9d6e0bfda523b3d6b1b1fe9f7973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 16:25:36 +0200 Subject: [PATCH 039/523] fights a flaky spec --- spec/features/account_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/features/account_spec.rb b/spec/features/account_spec.rb index d1c547185..5561e89d4 100644 --- a/spec/features/account_spec.rb +++ b/spec/features/account_spec.rb @@ -112,7 +112,11 @@ feature 'Account' do end scenario 'Errors editing credentials' do - visit account_path + visit root_path + + click_link "My account" + + expect(current_path).to eq(account_path) click_link 'Change my credentials' click_button 'Update' From 250680439371699787d033076b960b71297e35dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 27 Oct 2016 15:52:07 +0200 Subject: [PATCH 040/523] adds fields and i18n keys to admin poll form --- app/views/admin/poll/polls/_form.html.erb | 16 ++++++++++++++-- config/i18n-tasks.yml | 1 + config/locales/admin.en.yml | 12 ++++-------- config/locales/admin.es.yml | 14 +++++--------- config/locales/responders.es.yml | 4 ++-- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 77961912c..9926c679a 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -2,8 +2,20 @@
    <%= f.text_field :name, - placeholder: t('admin.polls.new.name'), - label: t("admin.polls.new.name") %> + placeholder: t('admin.polls.form.name'), + label: t("admin.polls.form.name") %> +
    +
    + +
    +
    + + +
    + +
    + +
    diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 5c5898783..2cf89fe64 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -120,6 +120,7 @@ ignore_unused: - 'admin.activity.show.filter*' - 'admin.comments.index.hidden_*' - 'admin.settings.index.features.*' + - 'admin.polls.*.submit_button' - 'moderation.comments.index.filter*' - 'moderation.comments.index.order*' - 'moderation.debates.index.filter*' diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 6c42ac23e..1d80aa4cd 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -160,18 +160,14 @@ en: status: "Status" new: title: "New poll" - name: "Name" - reference: "Reference number" - open_date: "Open date" - close_date: "Close date" submit_button: "Create poll" edit: title: "Edit poll" - name: "Name" - reference: "Reference number" - open_date: "Open date" - close_date: "Close date" submit_button: "Update poll" + form: + name: "Name" + starts_at: "Open date" + ends_at: "Close date" show: no_booths: "There are no booths in this poll." add_booth: "Add booth" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 024f6abe2..cce743dcc 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -105,7 +105,7 @@ es: moderators: Moderadores valuators: Evaluadores poll_officers: Presidentes de mesa - polls: Votaciones físicas + polls: Votaciones officials: Cargos públicos organizations: Organizaciones settings: Configuración global @@ -160,18 +160,14 @@ es: status: "Estado" new: title: "Nueva votación" - name: "Nombre" - reference: "Número de referencia" - open_date: "Fecha de apertura" - close_date: "Fecha de cierre" submit_button: "Crear votación" edit: title: "Editar votación" - name: "Nombre" - reference: "Número de referencia" - open_date: "Fecha de apertura" - close_date: "Fecha de cierre" submit_button: "Actualizar votación" + form: + name: "Nombre" + starts_at: "Fecha de apertura" + ends_at: "Fecha de cierre" show: no_booths: "No hay urnas en esta votación." add_booth: "Añadir urna" diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index 105b00903..54c4c7035 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -6,7 +6,7 @@ es: notice: "%{resource_name} creado correctamente." debate: "Debate creado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente." - poll: "Votación presencial creada correctamente." + poll: "Votación creada correctamente." poll_booth: "Urna creada correctamente." proposal: "Propuesta creada correctamente." proposal_notification: "Tu message ha sido enviado correctamente." @@ -17,7 +17,7 @@ es: notice: "%{resource_name} actualizado correctamente." debate: "Debate actualizado correctamente." proposal: "Propuesta actualizada correctamente." - poll: "Votación presencial actualizada correctamente." + poll: "Votación actualizada correctamente." poll_booth: "Urna actualizada correctamente." spending_proposal: "Propuesta de inversión actualizada correctamente." destroy: From 85aba10798314075c4559f5db59a0c54412a7d0a Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 28 Oct 2016 18:02:28 +0200 Subject: [PATCH 041/523] Initial work in Poll::Question --- app/models/poll/question.rb | 47 +++++++++++++++++++ .../20161028104156_create_poll_questions.rb | 21 +++++++++ ...28143204_create_geozones_poll_questions.rb | 10 ++++ db/schema.rb | 35 +++++++++++++- spec/factories.rb | 9 ++++ spec/models/poll/question_spec.rb | 27 +++++++++++ 6 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 app/models/poll/question.rb create mode 100644 db/migrate/20161028104156_create_poll_questions.rb create mode 100644 db/migrate/20161028143204_create_geozones_poll_questions.rb create mode 100644 spec/models/poll/question_spec.rb diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb new file mode 100644 index 000000000..b8815cf2d --- /dev/null +++ b/app/models/poll/question.rb @@ -0,0 +1,47 @@ +class Poll::Question < ActiveRecord::Base + include Measurable + + acts_as_paranoid column: :hidden_at + include ActsAsParanoidAliases + + belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' + + has_many :comments, as: :commentable + has_many :answers + has_and_belongs_to_many :geozones + belongs_to :proposal + + validates :title, presence: true + validates :question, presence: true + validates :summary, presence: true + validates :author, presence: true + + validates :title, length: { in: 4..Poll::Question.title_max_length } + validates :description, length: { maximum: Poll::Question.description_max_length } + validates :question, length: { in: 10..Poll::Question.question_max_length } + + scope :sort_for_list, -> { order('proposal_id IS NULL', :created_at)} + scope :for_render, -> { includes(:author, :proposal) } + + def description + super.try :html_safe + 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.description = proposal.description + self.summary = proposal.summary + self.question = proposal.question + self.geozones = Geozone.all + end + end + +end diff --git a/db/migrate/20161028104156_create_poll_questions.rb b/db/migrate/20161028104156_create_poll_questions.rb new file mode 100644 index 000000000..13c8ac1e8 --- /dev/null +++ b/db/migrate/20161028104156_create_poll_questions.rb @@ -0,0 +1,21 @@ +class CreatePollQuestions < ActiveRecord::Migration + def change + create_table :poll_questions do |t| + t.references :proposal, index: true, foreign_key: true + t.references :poll, index: true, foreign_key: true + t.references :author, index: true # foreign key added later due to rails 4 + t.string :author_visible_name + t.string :title + t.string :question + t.string :summary + t.string :valid_answers + t.text :description + t.integer :comments_count + t.datetime :hidden_at + + t.timestamps + end + + add_foreign_key :poll_questions, :users, column: :author_id + end +end diff --git a/db/migrate/20161028143204_create_geozones_poll_questions.rb b/db/migrate/20161028143204_create_geozones_poll_questions.rb new file mode 100644 index 000000000..68077c510 --- /dev/null +++ b/db/migrate/20161028143204_create_geozones_poll_questions.rb @@ -0,0 +1,10 @@ +class CreateGeozonesPollQuestions < ActiveRecord::Migration + def change + create_table :geozones_poll_questions do |t| + t.references :geozone, index: true, foreign_key: true + t.integer :question_id, index: true + end + + add_foreign_key :geozones_poll_questions, :poll_questions, column: :question_id + end +end diff --git a/db/schema.rb b/db/schema.rb index d1862bf11..a8e6f83b3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161020112156) do +ActiveRecord::Schema.define(version: 20161028143204) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -211,6 +211,14 @@ ActiveRecord::Schema.define(version: 20161020112156) do t.string "census_code" end + create_table "geozones_poll_questions", force: :cascade do |t| + t.integer "geozone_id" + t.integer "question_id" + end + + add_index "geozones_poll_questions", ["geozone_id"], name: "index_geozones_poll_questions_on_geozone_id", using: :btree + add_index "geozones_poll_questions", ["question_id"], name: "index_geozones_poll_questions_on_question_id", using: :btree + create_table "identities", force: :cascade do |t| t.integer "user_id" t.string "provider" @@ -287,6 +295,26 @@ ActiveRecord::Schema.define(version: 20161020112156) do t.datetime "updated_at", null: false end + create_table "poll_questions", force: :cascade do |t| + t.integer "proposal_id" + t.integer "poll_id" + t.integer "author_id" + t.string "author_visible_name" + t.string "title" + t.string "question" + t.string "summary" + t.string "valid_answers" + t.text "description" + t.integer "comments_count" + t.datetime "hidden_at" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "poll_questions", ["author_id"], name: "index_poll_questions_on_author_id", using: :btree + add_index "poll_questions", ["poll_id"], name: "index_poll_questions_on_poll_id", using: :btree + add_index "poll_questions", ["proposal_id"], name: "index_poll_questions_on_proposal_id", using: :btree + create_table "poll_voters", force: :cascade do |t| t.integer "booth_id" t.string "document_number" @@ -583,12 +611,17 @@ ActiveRecord::Schema.define(version: 20161020112156) do add_foreign_key "annotations", "users" add_foreign_key "failed_census_calls", "users" add_foreign_key "flags", "users" + add_foreign_key "geozones_poll_questions", "geozones" + add_foreign_key "geozones_poll_questions", "poll_questions", column: "question_id" add_foreign_key "identities", "users" add_foreign_key "locks", "users" add_foreign_key "managers", "users" add_foreign_key "moderators", "users" add_foreign_key "notifications", "users" add_foreign_key "organizations", "users" + add_foreign_key "poll_questions", "polls" + add_foreign_key "poll_questions", "proposals" + add_foreign_key "poll_questions", "users", column: "author_id" add_foreign_key "users", "geozones" add_foreign_key "valuators", "users" end diff --git a/spec/factories.rb b/spec/factories.rb index 21abd6554..abeff338c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -296,6 +296,15 @@ FactoryGirl.define do end end + factory :poll_question, class: 'Poll::Question' do + association :author, factory: :user + sequence(:title) { |n| "Question title #{n}" } + sequence(:summary) { |n| "Question summary #{n}" } + sequence(:description) { |n| "Question description #{n}" } + sequence(:question) { |n| "Question question #{n}" } + valid_answers { Faker::Lorem.words(3).join(', ') } + end + factory :organization do user responsible_name "Johnny Utah" diff --git a/spec/models/poll/question_spec.rb b/spec/models/poll/question_spec.rb new file mode 100644 index 000000000..92e019027 --- /dev/null +++ b/spec/models/poll/question_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +RSpec.describe Poll::Question, type: :model do + + describe "#valid_answers" do + it "gets a comma-separated string, but returns an array" do + q = create(:poll_question, valid_answers: "Yes, No") + expect(q.valid_answers).to eq(["Yes", "No"]) + end + end + + describe "#copy_attributes_from_proposal" do + it "copies the attributes from the proposal" do + create_list(:geozone, 3) + p = create(:proposal) + q = create(:poll_question) + q.copy_attributes_from_proposal(p) + expect(q.author).to eq(p.author) + expect(q.author_visible_name).to eq(p.author.name) + expect(q.proposal_id).to eq(p.id) + expect(q.title).to eq(p.title) + expect(q.question).to eq(p.question) + expect(q.geozones).to eq(Geozone.all) + end + end + +end From 3eca3faacdbd6be272a2a72adb3a9ef0692b0afd Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 31 Oct 2016 14:13:56 +0100 Subject: [PATCH 042/523] First version of Polls Controller --- app/controllers/polls_controller.rb | 13 +++++++++++++ app/models/abilities/everyone.rb | 1 + app/views/polls/index.html.erb | 3 +++ app/views/polls/show.html.erb | 1 + config/routes.rb | 4 ++++ spec/features/polls_spec.rb | 22 ++++++++++++++++++++++ 6 files changed, 44 insertions(+) create mode 100644 app/controllers/polls_controller.rb create mode 100644 app/views/polls/index.html.erb create mode 100644 app/views/polls/show.html.erb create mode 100644 spec/features/polls_spec.rb diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb new file mode 100644 index 000000000..0c802e17f --- /dev/null +++ b/app/controllers/polls_controller.rb @@ -0,0 +1,13 @@ +class PollsController < ApplicationController + + load_and_authorize_resource + + def index + + end + + def show + + end + +end diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb index 39a7f69f5..8424500a3 100644 --- a/app/models/abilities/everyone.rb +++ b/app/models/abilities/everyone.rb @@ -6,6 +6,7 @@ module Abilities can [:read, :map], Debate can [:read, :map, :summary], Proposal can :read, Comment + can :read, Poll can :read, SpendingProposal can :read, Legislation can :read, User diff --git a/app/views/polls/index.html.erb b/app/views/polls/index.html.erb new file mode 100644 index 000000000..3a1d7f3b5 --- /dev/null +++ b/app/views/polls/index.html.erb @@ -0,0 +1,3 @@ +<% @polls.each do |poll| %> + <%= link_to poll.name, poll %> +<% end %> diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb new file mode 100644 index 000000000..01749b19a --- /dev/null +++ b/app/views/polls/show.html.erb @@ -0,0 +1 @@ +<%= @poll.name %> diff --git a/config/routes.rb b/config/routes.rb index 16625aa7c..793a97f42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -85,6 +85,10 @@ Rails.application.routes.draw do get :search, on: :collection end + resources :polls, only: [:show, :index] do + resources :questions, only: [:show, :index] + end + resources :users, only: [:show] do resources :direct_messages, only: [:new, :create, :show] end diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb new file mode 100644 index 000000000..d3c101ed8 --- /dev/null +++ b/spec/features/polls_spec.rb @@ -0,0 +1,22 @@ +# coding: utf-8 +require 'rails_helper' + +feature 'Polls' do + + scenario 'Polls can be listed' do + polls = create_list(:poll, 3) + + visit polls_path + + polls.each do |poll| + expect(page).to have_link(poll.name) + end + end + + scenario 'Polls can be seen' do + poll = create(:poll) + visit poll_path(poll) + expect(page).to have_content(poll.name) + end +end + From 1aab7805920b66fcd2ebecb30ac6a4903992c49e Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 31 Oct 2016 14:27:25 +0100 Subject: [PATCH 043/523] Starts adding questions to polls --- app/models/poll.rb | 3 ++- app/models/poll/question.rb | 1 + app/views/polls/show.html.erb | 4 ++++ spec/features/polls_spec.rb | 6 ++++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 4543a2544..11ac6ccb8 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,6 +1,7 @@ class Poll < ActiveRecord::Base has_many :booths has_many :voters, through: :booths, class_name: "Poll::Voter" + has_many :questions validates :name, presence: true -end \ No newline at end of file +end diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index b8815cf2d..75f78fb15 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -4,6 +4,7 @@ class Poll::Question < ActiveRecord::Base acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases + belongs_to :poll belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' has_many :comments, as: :commentable diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 01749b19a..e9eeb7ca2 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -1 +1,5 @@ <%= @poll.name %> + +<%= @poll.questions.sort_for_list.each do |question| %> + <%= question.title %> +<% end %> diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index d3c101ed8..a873c22f4 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -15,8 +15,14 @@ feature 'Polls' do scenario 'Polls can be seen' do poll = create(:poll) + questions = create_list(:poll_question, 5, poll: poll) + visit poll_path(poll) expect(page).to have_content(poll.name) + + questions.each do |question| + expect(page).to have_content(question.title) + end end end From 575aa62960b73a2f4a49225805a72941d8574e8c Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 31 Oct 2016 16:31:48 +0100 Subject: [PATCH 044/523] Starts introducing valid answers to poll questions --- app/controllers/polls_controller.rb | 2 +- app/models/poll/question.rb | 3 +++ app/views/polls/show.html.erb | 9 +++++++-- spec/features/polls_spec.rb | 7 ++++++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 0c802e17f..f6f155106 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -7,7 +7,7 @@ class PollsController < ApplicationController end def show - + @questions = @poll.questions.sort_for_list.for_render end end diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 75f78fb15..59ff11a70 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -23,6 +23,7 @@ class Poll::Question < ActiveRecord::Base scope :sort_for_list, -> { order('proposal_id IS NULL', :created_at)} scope :for_render, -> { includes(:author, :proposal) } + scope :by_geozone, -> (geozone_id) { joins(:geozones).where(geozones: {id: geozone_id}) } def description super.try :html_safe @@ -45,4 +46,6 @@ class Poll::Question < ActiveRecord::Base end end + + end diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index e9eeb7ca2..71870cedf 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -1,5 +1,10 @@ <%= @poll.name %> -<%= @poll.questions.sort_for_list.each do |question| %> - <%= question.title %> +<% @questions.each do |question| %> +
    + <%= question.title %> + <%= question.valid_answers.each do |valid_answer| %> + <%= link_to valid_answer %> + <% end %> +
    <% end %> diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index a873c22f4..f206407d2 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -21,7 +21,12 @@ feature 'Polls' do expect(page).to have_content(poll.name) questions.each do |question| - expect(page).to have_content(question.title) + within("#poll_question_#{question.id}") do + expect(page).to have_content(question.title) + question.valid_answers.each do |answer| + expect(page).to have_link(answer) + end + end end end end From 0305d2bd65229e6a1213a1361de5e22d3cbcdf70 Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 2 Nov 2016 17:49:34 +0100 Subject: [PATCH 045/523] Adds time scopes and methods to poll --- app/models/poll.rb | 16 ++++++++++++++++ spec/factories.rb | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/app/models/poll.rb b/app/models/poll.rb index 11ac6ccb8..cc731f0b5 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -4,4 +4,20 @@ class Poll < ActiveRecord::Base has_many :questions validates :name, presence: true + + scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.now, Time.now) } + scope :incoming, -> { where('? < starts_at', Time.now) } + scope :expired, -> { where('ends_at < ?', Time.now) } + + def current?(timestamp = DateTime.now) + starts_at <= timestamp && timestamp <= ends_at + end + + def incoming?(timestamp = DateTime.now) + timestamp < starts_at + end + + def expired?(timestamp = DateTime.now) + ends_at < timestamp + end end diff --git a/spec/factories.rb b/spec/factories.rb index abeff338c..7f9b0b63e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -265,6 +265,19 @@ FactoryGirl.define do factory :poll do sequence(:name) { |n| "Poll #{n}" } + + starts_at { 1.month.ago } + ends_at { 1.month.from_now } + + trait :incoming do + starts_at { 2.days.from_now } + ends_at { 1.month.from_now } + end + + trait :expired do + starts_at { 1.month.ago } + ends_at { 15.days.ago } + end end factory :poll_officer, class: 'Poll::Officer' do From 3d22c556e8c71c9610cf8b1b350fd918ae56834f Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 2 Nov 2016 17:50:08 +0100 Subject: [PATCH 046/523] Adds scenarios (some missing) for poll voting --- app/views/polls/_warnings.html.erb | 28 +++++ app/views/polls/show.html.erb | 15 ++- config/locales/en.yml | 10 ++ spec/features/polls_spec.rb | 182 +++++++++++++++++++++++++---- 4 files changed, 214 insertions(+), 21 deletions(-) create mode 100644 app/views/polls/_warnings.html.erb diff --git a/app/views/polls/_warnings.html.erb b/app/views/polls/_warnings.html.erb new file mode 100644 index 000000000..b6b44fbc0 --- /dev/null +++ b/app/views/polls/_warnings.html.erb @@ -0,0 +1,28 @@ +<% if current_user.nil? %> +
    +
    + <%= t("polls.show.cant_answer_not_logged_in", + signin: link_to(t("polls.show.signin"), new_user_session_path, class: "probe-message"), + signup: link_to(t("polls.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> +
    +
    +<% elsif current_user.unverified? %> +
    +
    + <%= t('polls.show.cant_answer_verify_html', + verify_link: link_to(t('polls.show.verify_link'), verification_path)) %> +
    +
    +<% elsif @poll.incoming? %> +
    +
    + <%= t('polls.show.cant_answer_incoming') %> +
    +
    +<% elsif @poll.expired? %> +
    +
    + <%= t('polls.show.cant_answer_expired') %> +
    +
    +<% end %> diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 71870cedf..90965e739 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -1,10 +1,23 @@ <%= @poll.name %> +<%= render 'warnings' %> + <% @questions.each do |question| %>
    <%= question.title %> + <%= question.valid_answers.each do |valid_answer| %> - <%= link_to valid_answer %> + <% if can? :answer, @poll %> + <%= link_to valid_answer %> + <% else %> + <%= valid_answer %> + <% end %> + <% end %> + + <% if false #wrong geozone %> +
    + <%= t('polls.show.cant_answer_wrong_geozone') %> +
    <% end %>
    <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 9230ecbf8..d139b724b 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -375,6 +375,16 @@ en: update: form: submit_button: Save changes + polls: + show: + cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate." + signin: Sign in + signup: Sign up + cant_answer_verify_html: "You must %{verify_link} in order to answer." + verify_link: "verify your account" + cant_answer_incoming: "This poll has not yet started." + cant_answer_expired: "This poll has finished." + cant_answer_wrong_geozone: "This enquiry is not available on your geozone." proposal_ballots: title: "Votings" description_html: "The following citizen proposals that have reached the required supports and will be voted." diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index f206407d2..a226f8a65 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -3,31 +3,173 @@ require 'rails_helper' feature 'Polls' do - scenario 'Polls can be listed' do - polls = create_list(:poll, 3) + context '#index' do - visit polls_path + scenario 'Polls can be listed' do + polls = create_list(:poll, 3) - polls.each do |poll| - expect(page).to have_link(poll.name) - end - end + visit polls_path - scenario 'Polls can be seen' do - poll = create(:poll) - questions = create_list(:poll_question, 5, poll: poll) - - visit poll_path(poll) - expect(page).to have_content(poll.name) - - questions.each do |question| - within("#poll_question_#{question.id}") do - expect(page).to have_content(question.title) - question.valid_answers.each do |answer| - expect(page).to have_link(answer) - end + polls.each do |poll| + expect(page).to have_link(poll.name) end end + + xscenario 'Filtering enquiries' do + create(:poll_question, poll: poll, title: "Open question") + create(:poll_question, :incoming, poll: poll, title: "Incoming question") + create(:poll_question, :expired, poll: poll, title: "Expired question") + + visit enquiries_path + expect(page).to have_content('Open question') + expect(page).to_not have_content('Incoming question') + expect(page).to_not have_content('Expired question') + + visit enquiries_path(filter: 'incoming') + expect(page).to_not have_content('Open question') + expect(page).to have_content('Incoming question') + expect(page).to_not have_content('Expired question') + + visit enquiries_path(filter: 'expired') + expect(page).to_not have_content('Open question') + expect(page).to_not have_content('Incoming question') + expect(page).to have_content('Expired question') + end + + xscenario "Current filter is properly highlighted" do + visit enquiries_path + expect(page).to_not have_link('Open') + expect(page).to have_link('Incoming') + expect(page).to have_link('Expired') + + visit enquiries_path(filter: 'incoming') + expect(page).to have_link('Open') + expect(page).to_not have_link('Incoming') + expect(page).to have_link('Expired') + + visit enquiries_path(filter: 'expired') + expect(page).to have_link('Open') + expect(page).to have_link('Incoming') + expect(page).to_not have_link('Expired') + end end + + context 'Show' do + let(:geozone) { create(:geozone) } + let(:poll) { create(:poll) } + + scenario 'Lists questions from proposals as well as regular ones' do + normal_question = create(:poll_question, poll: poll) + proposal_question = create(:poll_question, poll: poll, proposal: create(:proposal)) + + visit poll_path(poll) + expect(page).to have_content(poll.name) + + expect(page).to have_content(normal_question.title) + expect(page).to have_content(proposal_question.title) + end + + scenario 'Non-logged in users' do + create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + visit poll_path(poll) + + expect(page).to have_content('Han Solo') + expect(page).to have_content('Chewbacca') + expect(page).to have_content('You must Sign in or Sign up to participate') + + expect(page).to_not have_link('Han Solo') + expect(page).to_not have_link('Chewbacca') + end + + scenario 'Level 1 users' do + create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + login_as(create(:user, geozone: geozone)) + visit poll_path(poll) + + expect(page).to have_content('Han Solo') + expect(page).to have_content('Chewbacca') + expect(page).to have_content('You must verify your account in order to answer') + + expect(page).to_not have_link('Han Solo') + expect(page).to_not have_link('Chewbacca') + end + + scenario 'Level 2 users in an incoming question' do + incoming_poll = create(:poll, :incoming) + create(:poll_question, poll: incoming_poll, geozone_ids: [geozone.id], valid_answers: 'Rey, Finn') + login_as(create(:user, :level_two, geozone: geozone)) + + visit poll_path(incoming_poll) + + expect(page).to have_content('Rey') + expect(page).to have_content('Finn') + expect(page).to_not have_link('Rey') + expect(page).to_not have_link('Finn') + + expect(page).to have_content('This poll has not yet started') + end + + scenario 'Level 2 users in an expired question' do + expired_poll = create(:poll, :expired) + create(:poll_question, poll: expired_poll, geozone_ids: [geozone.id], valid_answers: 'Luke, Leia') + login_as(create(:user, :level_two, geozone: geozone)) + + visit poll_path(expired_poll) + + expect(page).to have_content('Luke') + expect(page).to have_content('Leia') + expect(page).to_not have_link('Luke') + expect(page).to_not have_link('Leia') + + expect(page).to have_content('This poll has finished') + end + + xscenario 'Level 2 users in an question for a geozone which is not theirs' do + create(:poll_question, poll: poll, geozone_ids: [], valid_answers: 'Vader, Palpatine') + login_as(create(:user, :level_two)) + + visit poll_path(poll) + + expect(page).to have_content('Vader') + expect(page).to have_content('Palpatine') + expect(page).to_not have_link('Vader') + expect(page).to_not have_link('Palpatine') + end + + xscenario 'Level 2 users who can answer' do + create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + login_as(create(:user, :level_two, geozone: geozone)) + visit poll_path(poll) + + expect(page).to have_link('Han Solo') + expect(page).to have_link('Chewbacca') + end + + xscenario 'Level 2 users who have already answered' do + question = create(:poll_question, poll: poll, geozone_ids:[geozone.id], valid_answers: 'Han Solo, Chewbacca') + user = create(:user, :level_two, geozone: geozone) + create(:question_answer, question: question, author: user, answer: 'Chewbacca') + login_as user + visit poll_path(poll) + + expect(page).to have_link('Han Solo') + expect(page).to_not have_link('Chewbacca') + expect(page).to have_content('Chewbacca') + end + + xscenario 'Level 2 users answering', :js do + create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + user = create(:user, :level_two, geozone: geozone) + login_as user + visit poll_path(poll) + + click_link 'Han Solo' + + expect(page).to_not have_link('Han Solo') + expect(page).to have_link('Chewbacca') + end + + end + end From 35a5136d9ff3af1f71f83221921ad42cf7064a18 Mon Sep 17 00:00:00 2001 From: kikito Date: Thu, 3 Nov 2016 17:52:15 +0100 Subject: [PATCH 047/523] Implements filtering in polls/index --- app/controllers/polls_controller.rb | 4 ++- app/models/poll.rb | 2 ++ app/views/polls/index.html.erb | 4 +++ spec/features/polls_spec.rb | 46 ++++++++++++++--------------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index f6f155106..7433ea95b 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -2,8 +2,10 @@ class PollsController < ApplicationController load_and_authorize_resource - def index + has_filters %w{current expired incoming} + def index + @polls = @polls.send(@current_filter).sort_for_list.page(params[:page]) end def show diff --git a/app/models/poll.rb b/app/models/poll.rb index cc731f0b5..a4435d321 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -9,6 +9,8 @@ class Poll < ActiveRecord::Base scope :incoming, -> { where('? < starts_at', Time.now) } scope :expired, -> { where('ends_at < ?', Time.now) } + scope :sort_for_list, -> { order(:starts_at) } + def current?(timestamp = DateTime.now) starts_at <= timestamp && timestamp <= ends_at end diff --git a/app/views/polls/index.html.erb b/app/views/polls/index.html.erb index 3a1d7f3b5..4b39e09af 100644 --- a/app/views/polls/index.html.erb +++ b/app/views/polls/index.html.erb @@ -1,3 +1,7 @@ +<%= render 'shared/filter_subnav', i18n_namespace: "polls.index" %> + <% @polls.each do |poll| %> <%= link_to poll.name, poll %> <% end %> + +<%= paginate @polls %> diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index a226f8a65..4ef146f72 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -15,40 +15,40 @@ feature 'Polls' do end end - xscenario 'Filtering enquiries' do - create(:poll_question, poll: poll, title: "Open question") - create(:poll_question, :incoming, poll: poll, title: "Incoming question") - create(:poll_question, :expired, poll: poll, title: "Expired question") + scenario 'Filtering polls' do + create(:poll, name: "Current poll") + create(:poll, :incoming, name: "Incoming poll") + create(:poll, :expired, name: "Expired poll") - visit enquiries_path - expect(page).to have_content('Open question') - expect(page).to_not have_content('Incoming question') - expect(page).to_not have_content('Expired question') + visit polls_path + expect(page).to have_content('Current poll') + expect(page).to_not have_content('Incoming poll') + expect(page).to_not have_content('Expired poll') - visit enquiries_path(filter: 'incoming') - expect(page).to_not have_content('Open question') - expect(page).to have_content('Incoming question') - expect(page).to_not have_content('Expired question') + visit polls_path(filter: 'incoming') + expect(page).to_not have_content('Current poll') + expect(page).to have_content('Incoming poll') + expect(page).to_not have_content('Expired poll') - visit enquiries_path(filter: 'expired') - expect(page).to_not have_content('Open question') - expect(page).to_not have_content('Incoming question') - expect(page).to have_content('Expired question') + visit polls_path(filter: 'expired') + expect(page).to_not have_content('Current poll') + expect(page).to_not have_content('Incoming poll') + expect(page).to have_content('Expired poll') end - xscenario "Current filter is properly highlighted" do - visit enquiries_path - expect(page).to_not have_link('Open') + scenario "Current filter is properly highlighted" do + visit polls_path + expect(page).to_not have_link('Current') expect(page).to have_link('Incoming') expect(page).to have_link('Expired') - visit enquiries_path(filter: 'incoming') - expect(page).to have_link('Open') + visit polls_path(filter: 'incoming') + expect(page).to have_link('Current') expect(page).to_not have_link('Incoming') expect(page).to have_link('Expired') - visit enquiries_path(filter: 'expired') - expect(page).to have_link('Open') + visit polls_path(filter: 'expired') + expect(page).to have_link('Current') expect(page).to have_link('Incoming') expect(page).to_not have_link('Expired') end From f821d7beb734d9d7da2f9025d11de581b8e5b328 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 10:37:22 +0100 Subject: [PATCH 048/523] Implements abilities for poll & poll_question --- app/models/abilities/common.rb | 2 ++ spec/models/abilities/common_spec.rb | 24 +++++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index f82e78b58..5635cc7d7 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -48,6 +48,8 @@ module Abilities can :create, SpendingProposal can :create, DirectMessage can :show, DirectMessage, sender_id: user.id + can(:answer, Poll, Poll.current){ |poll| poll.current? } + can :answer, Poll::Question, geozones: {id: user.geozone_id} end can [:create, :show], ProposalNotification, proposal: { author_id: user.id } diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index ab14c01bd..6be4e0dce 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -3,8 +3,9 @@ require 'cancan/matchers' describe "Abilities::Common" do subject(:ability) { Ability.new(user) } + let(:geozone) { create(:geozone) } - let(:user) { create(:user) } + let(:user) { create(:user, geozone: geozone) } let(:debate) { create(:debate) } let(:comment) { create(:comment) } @@ -13,6 +14,13 @@ describe "Abilities::Common" do let(:own_comment) { create(:comment, author: user) } let(:own_proposal) { create(:proposal, author: user) } + let(:current_poll) { create(:poll) } + let(:incoming_poll) { create(:poll, :incoming) } + let(:expired_poll) { create(:poll, :expired) } + + let(:poll_question_from_own_geozone) { create(:poll_question, geozones: [geozone]) } + let(:poll_question_from_other_geozone) { create(:poll_question, geozones: [create(:geozone)]) } + it { should be_able_to(:index, Debate) } it { should be_able_to(:show, debate) } it { should be_able_to(:vote, debate) } @@ -103,6 +111,13 @@ describe "Abilities::Common" do it { should be_able_to(:create, DirectMessage) } it { should be_able_to(:show, own_direct_message) } it { should_not be_able_to(:show, create(:direct_message)) } + + it { should be_able_to(:answer, current_poll) } + it { should_not be_able_to(:answer, expired_poll) } + it { should_not be_able_to(:answer, incoming_poll) } + + it { should be_able_to(:answer, poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } end describe "when level 3 verified" do @@ -121,5 +136,12 @@ describe "Abilities::Common" do it { should be_able_to(:create, DirectMessage) } it { should be_able_to(:show, own_direct_message) } it { should_not be_able_to(:show, create(:direct_message)) } + + it { should be_able_to(:answer, current_poll) } + it { should_not be_able_to(:answer, expired_poll) } + it { should_not be_able_to(:answer, incoming_poll) } + + it { should be_able_to(:answer, poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } end end From 09cb25af30d6a32738d6dccbbe77f3c4ee63d5e3 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 16:27:34 +0100 Subject: [PATCH 049/523] Adds all_geozones to poll_questions --- .../20161107124207_add_all_geozones_to_poll_questions.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20161107124207_add_all_geozones_to_poll_questions.rb diff --git a/db/migrate/20161107124207_add_all_geozones_to_poll_questions.rb b/db/migrate/20161107124207_add_all_geozones_to_poll_questions.rb new file mode 100644 index 000000000..15ed41ba5 --- /dev/null +++ b/db/migrate/20161107124207_add_all_geozones_to_poll_questions.rb @@ -0,0 +1,5 @@ +class AddAllGeozonesToPollQuestions < ActiveRecord::Migration + def change + add_column :poll_questions, :all_geozones, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index a8e6f83b3..4e5e3d9e0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161028143204) do +ActiveRecord::Schema.define(version: 20161107124207) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -309,6 +309,7 @@ ActiveRecord::Schema.define(version: 20161028143204) do t.datetime "hidden_at" t.datetime "created_at" t.datetime "updated_at" + t.boolean "all_geozones", default: false end add_index "poll_questions", ["author_id"], name: "index_poll_questions_on_author_id", using: :btree From fd3f00d61ae91cee43191c006e49e5b499831718 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 16:27:48 +0100 Subject: [PATCH 050/523] Adds missing poll to poll_question factory --- spec/factories.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/factories.rb b/spec/factories.rb index 7f9b0b63e..219334b85 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -310,6 +310,7 @@ FactoryGirl.define do end factory :poll_question, class: 'Poll::Question' do + poll association :author, factory: :user sequence(:title) { |n| "Question title #{n}" } sequence(:summary) { |n| "Question summary #{n}" } From d39f19abb8e972edc2a291ca6ca043ca5a63ac2a Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 16:28:39 +0100 Subject: [PATCH 051/523] Defines Poll::Question#answerable_by?(user) and uses it in abilities --- app/models/abilities/common.rb | 4 ++- app/models/poll/question.rb | 11 +++++++ spec/models/abilities/common_spec.rb | 47 ++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 5635cc7d7..9d6ad84a8 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -49,7 +49,9 @@ module Abilities can :create, DirectMessage can :show, DirectMessage, sender_id: user.id can(:answer, Poll, Poll.current){ |poll| poll.current? } - can :answer, Poll::Question, geozones: {id: user.geozone_id} + can(:answer, Poll::Question, Poll::Question.answerable_by(user)) do |question| + question.answerable_by?(user) + end end can [:create, :show], ProposalNotification, proposal: { author_id: user.id } diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 59ff11a70..6d56a31f2 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -46,6 +46,17 @@ class Poll::Question < ActiveRecord::Base end end + def answerable_by?(user) + user.present? && poll.current? && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) + end + def self.answerable_by(user) + return where(false) unless user.present? + where(poll_id: Poll.current.pluck(:id)) + .joins(:geozones) + .where('poll_questions.all_geozones = ? or geozones.id = ?', + true, + user.geozone_id || -1) # user.geozone_id can be nil, which would throw errors on sql + end end diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index 6be4e0dce..59618f785 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -20,6 +20,13 @@ describe "Abilities::Common" do let(:poll_question_from_own_geozone) { create(:poll_question, geozones: [geozone]) } let(:poll_question_from_other_geozone) { create(:poll_question, geozones: [create(:geozone)]) } + let(:poll_question_from_all_geozones) { create(:poll_question, all_geozones: true) } + let(:expired_poll_question_from_own_geozone) { create(:poll_question, poll: expired_poll, geozones: [geozone]) } + let(:expired_poll_question_from_other_geozone) { create(:poll_question, poll: expired_poll, geozones: [create(:geozone)]) } + let(:expired_poll_question_from_all_geozones) { create(:poll_question, poll: expired_poll, all_geozones: true) } + let(:incoming_poll_question_from_own_geozone) { create(:poll_question, poll: incoming_poll, geozones: [geozone]) } + let(:incoming_poll_question_from_other_geozone) { create(:poll_question, poll: incoming_poll, geozones: [create(:geozone)]) } + let(:incoming_poll_question_from_all_geozones) { create(:poll_question, poll: incoming_poll, all_geozones: true) } it { should be_able_to(:index, Debate) } it { should be_able_to(:show, debate) } @@ -117,7 +124,27 @@ describe "Abilities::Common" do it { should_not be_able_to(:answer, incoming_poll) } it { should be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + + context "without geozone" do + before(:each) { user.geozone = nil } + it { should_not be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + end end describe "when level 3 verified" do @@ -142,6 +169,26 @@ describe "Abilities::Common" do it { should_not be_able_to(:answer, incoming_poll) } it { should be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + + context "without geozone" do + before(:each) { user.geozone = nil } + it { should_not be_able_to(:answer, poll_question_from_own_geozone ) } + it { should be_able_to(:answer, poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, expired_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, expired_poll_question_from_other_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_own_geozone ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_all_geozones ) } + it { should_not be_able_to(:answer, incoming_poll_question_from_other_geozone ) } + end end end From 83fd70b0486ce81a0ecf57e254884c87f7648c64 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 17:34:24 +0100 Subject: [PATCH 052/523] Extracts some logic from poll_question to poll --- app/models/poll.rb | 9 +++++++++ app/models/poll/question.rb | 7 ++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index a4435d321..caa374dc8 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -22,4 +22,13 @@ class Poll < ActiveRecord::Base def expired?(timestamp = DateTime.now) ends_at < timestamp end + + def answerable_by?(user) + user.present? && user.level_two_or_three_verified? && current? + end + + def self.answerable_by(user) + return none if user.nil? || user.unverified? + current + end end diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 6d56a31f2..d6534e420 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -47,12 +47,13 @@ class Poll::Question < ActiveRecord::Base end def answerable_by?(user) - user.present? && poll.current? && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) + poll.answerable_by?(user) && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) end def self.answerable_by(user) - return where(false) unless user.present? - where(poll_id: Poll.current.pluck(:id)) + return none if user.nil? || user.unverified? + + where(poll_id: Poll.answerable_by(user).pluck(:id)) .joins(:geozones) .where('poll_questions.all_geozones = ? or geozones.id = ?', true, From 3255ca700f6d40c4509e782ce0e6cad56aa3aa64 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 17:42:52 +0100 Subject: [PATCH 053/523] User new answerable_by method in ability --- app/models/abilities/common.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 9d6ad84a8..36ce698b1 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -48,7 +48,7 @@ module Abilities can :create, SpendingProposal can :create, DirectMessage can :show, DirectMessage, sender_id: user.id - can(:answer, Poll, Poll.current){ |poll| poll.current? } + can(:answer, Poll, Poll.answerable_by(user)){ |poll| poll.answerable_by?(user) } can(:answer, Poll::Question, Poll::Question.answerable_by(user)) do |question| question.answerable_by?(user) end From 506cf0dd7090199cc0c9680296ad52b320e12ac2 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 7 Nov 2016 17:43:53 +0100 Subject: [PATCH 054/523] Refactors polls_controller using answerable_by. Implements more specs --- app/controllers/polls_controller.rb | 5 ++- app/views/polls/_warnings.html.erb | 28 ------------- app/views/polls/show.html.erb | 62 +++++++++++++++++++++-------- config/locales/en.yml | 2 +- spec/features/polls_spec.rb | 7 +++- 5 files changed, 56 insertions(+), 48 deletions(-) delete mode 100644 app/views/polls/_warnings.html.erb diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 7433ea95b..28ce9c447 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -9,7 +9,10 @@ class PollsController < ApplicationController end def show - @questions = @poll.questions.sort_for_list.for_render + questions = @poll.questions.sort_for_list.for_render + + @answerable_questions = questions.answerable_by(current_user) + @non_answerable_questions = questions.where.not(id: @answerable_questions.pluck(:id)) end end diff --git a/app/views/polls/_warnings.html.erb b/app/views/polls/_warnings.html.erb deleted file mode 100644 index b6b44fbc0..000000000 --- a/app/views/polls/_warnings.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -<% if current_user.nil? %> -
    -
    - <%= t("polls.show.cant_answer_not_logged_in", - signin: link_to(t("polls.show.signin"), new_user_session_path, class: "probe-message"), - signup: link_to(t("polls.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> -
    -
    -<% elsif current_user.unverified? %> -
    -
    - <%= t('polls.show.cant_answer_verify_html', - verify_link: link_to(t('polls.show.verify_link'), verification_path)) %> -
    -
    -<% elsif @poll.incoming? %> -
    -
    - <%= t('polls.show.cant_answer_incoming') %> -
    -
    -<% elsif @poll.expired? %> -
    -
    - <%= t('polls.show.cant_answer_expired') %> -
    -
    -<% end %> diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 90965e739..a51f280fb 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -1,23 +1,53 @@ <%= @poll.name %> -<%= render 'warnings' %> - -<% @questions.each do |question| %> -
    - <%= question.title %> - - <%= question.valid_answers.each do |valid_answer| %> - <% if can? :answer, @poll %> - <%= link_to valid_answer %> - <% else %> - <%= valid_answer %> - <% end %> - <% end %> - - <% if false #wrong geozone %> +<% unless can?(:answer, @poll) %> +
    + <% if current_user.nil? %> +
    + <%= t("polls.show.cant_answer_not_logged_in", + signin: link_to(t("polls.show.signin"), new_user_session_path, class: "probe-message"), + signup: link_to(t("polls.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> +
    + <% elsif current_user.unverified? %>
    - <%= t('polls.show.cant_answer_wrong_geozone') %> + <%= t('polls.show.cant_answer_verify_html', + verify_link: link_to(t('polls.show.verify_link'), verification_path)) %> +
    + <% elsif @poll.incoming? %> +
    + <%= t('polls.show.cant_answer_incoming') %> +
    + <% elsif @poll.expired? %> +
    + <%= t('polls.show.cant_answer_expired') %>
    <% end %>
    <% end %> + +<% @answerable_questions.each do |question| %> +
    + <%= question.title %> + + <% question.valid_answers.each do |valid_answer| %> + <%= link_to valid_answer %> + <% end %> +
    +<% end %> + +<% if can?(:answer, @poll) && + @non_answerable_questions.present? %> +
    + <%= t('polls.show.cant_answer_wrong_geozone') %> +
    +<% end %> + +<% @non_answerable_questions.each do |question| %> +
    + <%= question.title %> + + <% question.valid_answers.each do |valid_answer| %> + <%= valid_answer %> + <% end %> +
    +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d139b724b..b032b5805 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -384,7 +384,7 @@ en: verify_link: "verify your account" cant_answer_incoming: "This poll has not yet started." cant_answer_expired: "This poll has finished." - cant_answer_wrong_geozone: "This enquiry is not available on your geozone." + cant_answer_wrong_geozone: "The following questions are not available in your geozone." proposal_ballots: title: "Votings" description_html: "The following citizen proposals that have reached the required supports and will be voted." diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index 4ef146f72..a0da259aa 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -86,9 +86,10 @@ feature 'Polls' do login_as(create(:user, geozone: geozone)) visit poll_path(poll) + expect(page).to have_content('You must verify your account in order to answer') + expect(page).to have_content('Han Solo') expect(page).to have_content('Chewbacca') - expect(page).to have_content('You must verify your account in order to answer') expect(page).to_not have_link('Han Solo') expect(page).to_not have_link('Chewbacca') @@ -124,12 +125,14 @@ feature 'Polls' do expect(page).to have_content('This poll has finished') end - xscenario 'Level 2 users in an question for a geozone which is not theirs' do + scenario 'Level 2 users in a poll with questions for a geozone which is not theirs' do create(:poll_question, poll: poll, geozone_ids: [], valid_answers: 'Vader, Palpatine') login_as(create(:user, :level_two)) visit poll_path(poll) + expect(page).to have_content('The following questions are not available in your geozone') + expect(page).to have_content('Vader') expect(page).to have_content('Palpatine') expect(page).to_not have_link('Vader') From 6dd2b54123e1a066cfce9e0e2f2900b16c6a9cf1 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 8 Nov 2016 15:52:13 +0100 Subject: [PATCH 055/523] Fixes bug in Poll::Question#answerable_by --- app/models/poll/question.rb | 4 ++-- spec/features/polls_spec.rb | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index d6534e420..ae90ada12 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -54,8 +54,8 @@ class Poll::Question < ActiveRecord::Base return none if user.nil? || user.unverified? where(poll_id: Poll.answerable_by(user).pluck(:id)) - .joins(:geozones) - .where('poll_questions.all_geozones = ? or geozones.id = ?', + .joins('LEFT OUTER JOIN "geozones_poll_questions" ON "geozones_poll_questions"."question_id" = "poll_questions"."id"') + .where('(poll_questions.all_geozones = ? or geozones_poll_questions.geozone_id = ?)', true, user.geozone_id || -1) # user.geozone_id can be nil, which would throw errors on sql end diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index a0da259aa..31e7e0d8b 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -148,6 +148,16 @@ feature 'Polls' do expect(page).to have_link('Chewbacca') end + scenario 'Level 2 users reading a all-geozones question' do + create(:poll_question, poll: poll, all_geozones: true, valid_answers: 'Han Solo, Chewbacca') + login_as(create(:user, :level_two, geozone: geozone)) + visit poll_path(poll) + save_and_open_page + + expect(page).to have_link('Han Solo') + expect(page).to have_link('Chewbacca') + end + xscenario 'Level 2 users who have already answered' do question = create(:poll_question, poll: poll, geozone_ids:[geozone.id], valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) From 4db6ae489f7226100868d9a6dcc310c23e35015f Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 8 Nov 2016 15:53:49 +0100 Subject: [PATCH 056/523] Adds new passing test to poll questions --- spec/features/polls_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index 31e7e0d8b..f44ccfd94 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -139,7 +139,7 @@ feature 'Polls' do expect(page).to_not have_link('Palpatine') end - xscenario 'Level 2 users who can answer' do + scenario 'Level 2 users reading a same-geozone question' do create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(poll) From 3ce7f671fbe129f74f1fd24dbf17da321efb95c9 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:08:15 +0100 Subject: [PATCH 057/523] Adds poll partial result --- ...20161107174423_create_poll_partial_result.rb | 14 ++++++++++++++ db/schema.rb | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20161107174423_create_poll_partial_result.rb diff --git a/db/migrate/20161107174423_create_poll_partial_result.rb b/db/migrate/20161107174423_create_poll_partial_result.rb new file mode 100644 index 000000000..a4f91a4f9 --- /dev/null +++ b/db/migrate/20161107174423_create_poll_partial_result.rb @@ -0,0 +1,14 @@ +class CreatePollPartialResult < ActiveRecord::Migration + def change + create_table :poll_partial_results do |t| + t.integer :question_id, index: true + t.integer :author_id, index: true + t.string :answer, index: true + t.integer :amount + t.string :origin, index: true + end + + add_foreign_key(:poll_partial_results, :users, column: :author_id) + add_foreign_key(:poll_partial_results, :poll_questions, column: :question_id) + end +end diff --git a/db/schema.rb b/db/schema.rb index 4e5e3d9e0..6a94a95dc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161107124207) do +ActiveRecord::Schema.define(version: 20161107174423) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -295,6 +295,19 @@ ActiveRecord::Schema.define(version: 20161107124207) do t.datetime "updated_at", null: false end + create_table "poll_partial_results", force: :cascade do |t| + t.integer "question_id" + t.integer "author_id" + t.string "answer" + t.integer "amount" + t.string "origin" + end + + add_index "poll_partial_results", ["answer"], name: "index_poll_partial_results_on_answer", using: :btree + add_index "poll_partial_results", ["author_id"], name: "index_poll_partial_results_on_author_id", using: :btree + add_index "poll_partial_results", ["origin"], name: "index_poll_partial_results_on_origin", using: :btree + add_index "poll_partial_results", ["question_id"], name: "index_poll_partial_results_on_question_id", using: :btree + create_table "poll_questions", force: :cascade do |t| t.integer "proposal_id" t.integer "poll_id" @@ -620,6 +633,8 @@ ActiveRecord::Schema.define(version: 20161107124207) do add_foreign_key "moderators", "users" add_foreign_key "notifications", "users" add_foreign_key "organizations", "users" + add_foreign_key "poll_partial_results", "poll_questions", column: "question_id" + add_foreign_key "poll_partial_results", "users", column: "author_id" add_foreign_key "poll_questions", "polls" add_foreign_key "poll_questions", "proposals" add_foreign_key "poll_questions", "users", column: "author_id" From 048ada3e175eb25f8e7e080a4a8bb022b9f578fe Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:08:32 +0100 Subject: [PATCH 058/523] Adds poll partial result --- app/models/poll/partial_result.rb | 18 ++++++++++++++++++ spec/models/poll/partial_result_spec.rb | 16 ++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 app/models/poll/partial_result.rb create mode 100644 spec/models/poll/partial_result_spec.rb diff --git a/app/models/poll/partial_result.rb b/app/models/poll/partial_result.rb new file mode 100644 index 000000000..202f147bd --- /dev/null +++ b/app/models/poll/partial_result.rb @@ -0,0 +1,18 @@ +class Poll::PartialResult < ActiveRecord::Base + + VALID_ORIGINS = %w{ web } + + belongs_to :question, -> { with_hidden } + belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' + + 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} + + scope :by_author, -> (author_id) { where(author_id: author_id) } + scope :by_question, -> (question_id) { where(question_id: question_id) } + + +end diff --git a/spec/models/poll/partial_result_spec.rb b/spec/models/poll/partial_result_spec.rb new file mode 100644 index 000000000..ef47ecd8c --- /dev/null +++ b/spec/models/poll/partial_result_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +describe Poll::PartialResult, type: :model do + + describe "validations" do + it "validates that the answers are included in the Enquiry'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 + + expect(build(:poll_partial_result, question: q, answer: 'Four')).to_not be_valid + end + end + +end From 63311d6cd1077173d68f226390a9e4f38ba47ba2 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:08:46 +0100 Subject: [PATCH 059/523] reimplements routes for questions --- config/routes.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 793a97f42..2e0283152 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,7 +86,9 @@ Rails.application.routes.draw do end resources :polls, only: [:show, :index] do - resources :questions, only: [:show, :index] + resources :questions, only: [] do + post :answer, on: :member + end end resources :users, only: [:show] do From 0c9e6db04d382a14f3598c1264839d797f985e17 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:10:11 +0100 Subject: [PATCH 060/523] Implements answers in a partial --- app/controllers/polls_controller.rb | 10 +++++++--- app/views/poll/questions/_answers.html.erb | 23 ++++++++++++++++++++++ app/views/polls/show.html.erb | 12 +++++------ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 app/views/poll/questions/_answers.html.erb diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 28ce9c447..9c83bc3e3 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -9,10 +9,14 @@ class PollsController < ApplicationController end def show - questions = @poll.questions.sort_for_list.for_render + @answerable_questions = @poll.questions.answerable_by(current_user).for_render.sort_for_list + @non_answerable_questions = @poll.questions.where.not(id: @answerable_questions.map(&:id)).for_render.sort_for_list - @answerable_questions = questions.answerable_by(current_user) - @non_answerable_questions = questions.where.not(id: @answerable_questions.pluck(:id)) + @answers_by_question_id = {} + poll_partial_results = Poll::PartialResult.by_question(@poll.question_ids).by_author(current_user.try(:id)) + poll_partial_results.each do |result| + @answers_by_question_id[result.question_id] = result.answer + end end end diff --git a/app/views/poll/questions/_answers.html.erb b/app/views/poll/questions/_answers.html.erb new file mode 100644 index 000000000..94eed7045 --- /dev/null +++ b/app/views/poll/questions/_answers.html.erb @@ -0,0 +1,23 @@ +
    + <% if can? :answer, question %> +
    + <% question.valid_answers.each do |answer| %> + <% if @answers_by_question_id[question.id] == answer %> + + <%= answer %> + + <% else %> + <%= link_to answer, + answer_poll_question_path(poll_id: question.poll_id, question_id: question.id, answer: answer), + method: :post, + remote: true, + class: "button secondary hollow" %> + <% end %> + <% end %> +
    + <% else %> + <% question.valid_answers.each do |answer| %> + <%= answer %> + <% end %> + <% end %> +
    diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index a51f280fb..6282b112f 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -29,9 +29,9 @@
    <%= question.title %> - <% question.valid_answers.each do |valid_answer| %> - <%= link_to valid_answer %> - <% end %> +
    + <%= render 'poll/questions/answers', question: question %> +
    <% end %> @@ -46,8 +46,8 @@
    <%= question.title %> - <% question.valid_answers.each do |valid_answer| %> - <%= valid_answer %> - <% end %> +
    + <%= render 'poll/questions/answers', question: question %> +
    <% end %> From 11a98dce07124be18a6ca1062234dfabcde406bd Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:10:36 +0100 Subject: [PATCH 061/523] Refactors in poll/question model --- app/models/poll/question.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index ae90ada12..d56990f17 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -9,6 +9,7 @@ class Poll::Question < ActiveRecord::Base has_many :comments, as: :commentable has_many :answers + has_many :partial_results has_and_belongs_to_many :geozones belongs_to :proposal @@ -21,7 +22,7 @@ class Poll::Question < ActiveRecord::Base validates :description, length: { maximum: Poll::Question.description_max_length } validates :question, length: { in: 10..Poll::Question.question_max_length } - scope :sort_for_list, -> { order('proposal_id IS NULL', :created_at)} + scope :sort_for_list, -> { order('poll_questions.proposal_id IS NULL', :created_at)} scope :for_render, -> { includes(:author, :proposal) } scope :by_geozone, -> (geozone_id) { joins(:geozones).where(geozones: {id: geozone_id}) } From 219e139efb9b129ca0f0521081bd2afb8d74ea52 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:10:56 +0100 Subject: [PATCH 062/523] Adds poll_partial_result factory --- app/controllers/polls/questions_controller.rb | 17 +++++++++++++++++ spec/factories.rb | 7 +++++++ 2 files changed, 24 insertions(+) create mode 100644 app/controllers/polls/questions_controller.rb diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb new file mode 100644 index 000000000..bebb7ab4a --- /dev/null +++ b/app/controllers/polls/questions_controller.rb @@ -0,0 +1,17 @@ +class Polls::QuestionsController < ApplicationController + + load_and_authorize_resource :poll + load_and_authorize_resource :question, through: :poll + + def answer + partial_result = @question.partial_results.find_or_initialize_by(author: current_user, + amount: 1, + origin: 'web') + + partial_result.answer = params[:answer] + partial_result.save! + + @answers_by_question_id = {@question.id => params[:answer]} + end + +end diff --git a/spec/factories.rb b/spec/factories.rb index 219334b85..78c6241d5 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -319,6 +319,13 @@ FactoryGirl.define do valid_answers { Faker::Lorem.words(3).join(', ') } end + factory :poll_partial_result, class: 'Poll::PartialResult' do + association :question, factory: :poll_question + association :author, factory: :user + origin { 'web' } + answer { question.verified_answers.sample } + end + factory :organization do user responsible_name "Johnny Utah" From e5e3fe32dad319e28bc714807d2a96ed76301f17 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:11:18 +0100 Subject: [PATCH 063/523] Removes save_and_open_page from spec --- spec/features/polls_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index f44ccfd94..4276c91f0 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -152,7 +152,6 @@ feature 'Polls' do create(:poll_question, poll: poll, all_geozones: true, valid_answers: 'Han Solo, Chewbacca') login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(poll) - save_and_open_page expect(page).to have_link('Han Solo') expect(page).to have_link('Chewbacca') From 38efad77f31995a012a88c945ea18e0a67d66f89 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 11 Nov 2016 19:11:53 +0100 Subject: [PATCH 064/523] Changes the way question#copy_attributes_from_proposal works --- app/models/poll/question.rb | 6 ++++-- config/locales/en.yml | 2 ++ spec/models/poll/question_spec.rb | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index d56990f17..13245c384 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -43,7 +43,8 @@ class Poll::Question < ActiveRecord::Base self.description = proposal.description self.summary = proposal.summary self.question = proposal.question - self.geozones = Geozone.all + self.all_geozones = true + self.valid_answers = I18n.t('poll_questions.default_valid_answers') end end @@ -56,9 +57,10 @@ class Poll::Question < ActiveRecord::Base where(poll_id: Poll.answerable_by(user).pluck(:id)) .joins('LEFT OUTER JOIN "geozones_poll_questions" ON "geozones_poll_questions"."question_id" = "poll_questions"."id"') - .where('(poll_questions.all_geozones = ? or geozones_poll_questions.geozone_id = ?)', + .where('(poll_questions.all_geozones = ? OR geozones_poll_questions.geozone_id = ?)', true, user.geozone_id || -1) # user.geozone_id can be nil, which would throw errors on sql + .distinct end end diff --git a/config/locales/en.yml b/config/locales/en.yml index b032b5805..7c9abd2b9 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -385,6 +385,8 @@ en: cant_answer_incoming: "This poll has not yet started." cant_answer_expired: "This poll has finished." cant_answer_wrong_geozone: "The following questions are not available in your geozone." + poll_questions: + default_valid_answers: "Yes, No" proposal_ballots: title: "Votings" description_html: "The following citizen proposals that have reached the required supports and will be voted." diff --git a/spec/models/poll/question_spec.rb b/spec/models/poll/question_spec.rb index 92e019027..6cb38d023 100644 --- a/spec/models/poll/question_spec.rb +++ b/spec/models/poll/question_spec.rb @@ -15,12 +15,13 @@ RSpec.describe Poll::Question, type: :model do p = create(:proposal) q = create(:poll_question) q.copy_attributes_from_proposal(p) + expect(q.valid_answers).to eq(['Yes', 'No']) expect(q.author).to eq(p.author) expect(q.author_visible_name).to eq(p.author.name) expect(q.proposal_id).to eq(p.id) expect(q.title).to eq(p.title) expect(q.question).to eq(p.question) - expect(q.geozones).to eq(Geozone.all) + expect(q.all_geozones).to be_true end end From 598b1b9c012979e819ca5b6ae1c5749d03726267 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 14 Nov 2016 13:35:23 +0100 Subject: [PATCH 065/523] Adds group by to answerable_by scope to avoid duplicates --- app/models/poll/question.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 13245c384..68f0be910 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -55,12 +55,12 @@ class Poll::Question < ActiveRecord::Base def self.answerable_by(user) return none if user.nil? || user.unverified? - where(poll_id: Poll.answerable_by(user).pluck(:id)) - .joins('LEFT OUTER JOIN "geozones_poll_questions" ON "geozones_poll_questions"."question_id" = "poll_questions"."id"') - .where('(poll_questions.all_geozones = ? OR geozones_poll_questions.geozone_id = ?)', - true, - user.geozone_id || -1) # user.geozone_id can be nil, which would throw errors on sql - .distinct + joins('LEFT JOIN "geozones_poll_questions" ON "geozones_poll_questions"."question_id" = "poll_questions"."id"') + .where('poll_questions.poll_id IN (?) AND (poll_questions.all_geozones = ? OR geozones_poll_questions.geozone_id = ?)', + Poll.answerable_by(user).pluck(:id), + true, + user.geozone_id || -1) # user.geozone_id can be nil, which would throw errors on sql + .group('poll_questions.id') end end From 1f9945d0aac761e0591302e5e401df7b91a02264 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 14 Nov 2016 13:36:00 +0100 Subject: [PATCH 066/523] Implements answering questions --- app/controllers/polls/questions_controller.rb | 2 +- app/views/{poll => polls}/questions/_answers.html.erb | 2 +- app/views/polls/questions/answer.js.erb | 1 + app/views/polls/show.html.erb | 4 ++-- config/routes.rb | 2 +- spec/features/polls_spec.rb | 6 +++--- 6 files changed, 9 insertions(+), 8 deletions(-) rename app/views/{poll => polls}/questions/_answers.html.erb (94%) create mode 100644 app/views/polls/questions/answer.js.erb diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index bebb7ab4a..dcf459485 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -1,7 +1,7 @@ class Polls::QuestionsController < ApplicationController load_and_authorize_resource :poll - load_and_authorize_resource :question, through: :poll + load_and_authorize_resource :question, class: 'Poll::Question', through: :poll def answer partial_result = @question.partial_results.find_or_initialize_by(author: current_user, diff --git a/app/views/poll/questions/_answers.html.erb b/app/views/polls/questions/_answers.html.erb similarity index 94% rename from app/views/poll/questions/_answers.html.erb rename to app/views/polls/questions/_answers.html.erb index 94eed7045..ee76706fc 100644 --- a/app/views/poll/questions/_answers.html.erb +++ b/app/views/polls/questions/_answers.html.erb @@ -8,7 +8,7 @@ <% else %> <%= link_to answer, - answer_poll_question_path(poll_id: question.poll_id, question_id: question.id, answer: answer), + answer_poll_question_path(poll_id: question.poll_id, id: question.id, answer: answer), method: :post, remote: true, class: "button secondary hollow" %> diff --git a/app/views/polls/questions/answer.js.erb b/app/views/polls/questions/answer.js.erb new file mode 100644 index 000000000..aabbd8d89 --- /dev/null +++ b/app/views/polls/questions/answer.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id(@question) %>_answers").html('<%= j render("polls/questions/answers", question: @question) %>'); diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 6282b112f..ad7818a78 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -30,7 +30,7 @@ <%= question.title %>
    - <%= render 'poll/questions/answers', question: question %> + <%= render 'polls/questions/answers', question: question %>
    <% end %> @@ -47,7 +47,7 @@ <%= question.title %>
    - <%= render 'poll/questions/answers', question: question %> + <%= render 'polls/questions/answers', question: question %>
  • <% end %> diff --git a/config/routes.rb b/config/routes.rb index 2e0283152..95e5a87b1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,7 +86,7 @@ Rails.application.routes.draw do end resources :polls, only: [:show, :index] do - resources :questions, only: [] do + resources :questions, only: [], controller: 'polls/questions' do post :answer, on: :member end end diff --git a/spec/features/polls_spec.rb b/spec/features/polls_spec.rb index 4276c91f0..9270d5696 100644 --- a/spec/features/polls_spec.rb +++ b/spec/features/polls_spec.rb @@ -157,10 +157,10 @@ feature 'Polls' do expect(page).to have_link('Chewbacca') end - xscenario 'Level 2 users who have already answered' do + scenario 'Level 2 users who have already answered' do question = create(:poll_question, poll: poll, geozone_ids:[geozone.id], valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) - create(:question_answer, question: question, author: user, answer: 'Chewbacca') + create(:poll_partial_result, question: question, author: user, answer: 'Chewbacca') login_as user visit poll_path(poll) @@ -169,7 +169,7 @@ feature 'Polls' do expect(page).to have_content('Chewbacca') end - xscenario 'Level 2 users answering', :js do + scenario 'Level 2 users answering', :js do create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) login_as user From 1ca821c5205a4b93c2d56cf69e1b77811b2c3bea Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 14 Sep 2016 13:53:35 +0200 Subject: [PATCH 067/523] creates polling officers from admin --- .../admin/poll/officers_controller.rb | 32 +++++++++++++ app/helpers/admin_helper.rb | 2 +- app/models/abilities/administrator.rb | 1 + app/models/poll.rb | 2 + app/models/poll/officer.rb | 8 ++++ app/views/admin/_menu.html.erb | 6 +++ app/views/admin/poll/_menu.html.erb | 1 + .../admin/poll/officers/_officer.html.erb | 26 +++++++++++ app/views/admin/poll/officers/index.html.erb | 46 +++++++++++++++++++ app/views/admin/poll/officers/search.js.erb | 1 + .../admin/poll/officers/user_not_found.js.erb | 1 + config/locales/admin.en.yml | 11 +++++ config/locales/admin.es.yml | 11 +++++ config/routes.rb | 6 +++ db/migrate/20160914110004_create_polls.rb | 7 +++ .../20160914110039_create_poll_officers.rb | 7 +++ db/schema.rb | 8 ++++ spec/factories.rb | 4 ++ spec/features/admin/poll/officers_spec.rb | 36 +++++++++++++++ 19 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/poll/officers_controller.rb create mode 100644 app/models/poll.rb create mode 100644 app/models/poll/officer.rb create mode 100644 app/views/admin/poll/_menu.html.erb create mode 100644 app/views/admin/poll/officers/_officer.html.erb create mode 100644 app/views/admin/poll/officers/index.html.erb create mode 100644 app/views/admin/poll/officers/search.js.erb create mode 100644 app/views/admin/poll/officers/user_not_found.js.erb create mode 100644 db/migrate/20160914110004_create_polls.rb create mode 100644 db/migrate/20160914110039_create_poll_officers.rb create mode 100644 spec/features/admin/poll/officers_spec.rb diff --git a/app/controllers/admin/poll/officers_controller.rb b/app/controllers/admin/poll/officers_controller.rb new file mode 100644 index 000000000..5495d390c --- /dev/null +++ b/app/controllers/admin/poll/officers_controller.rb @@ -0,0 +1,32 @@ +class Admin::Poll::OfficersController < Admin::BaseController + load_and_authorize_resource :officer, class: "Poll::Officer" + + def index + @officers = @officers.page(params[:page]) + end + + def search + @user = User.find_by(email: params[:email]) + + respond_to do |format| + if @user + @officer = Poll::Officer.find_or_initialize_by(user: @user) + format.js + else + format.js { render "user_not_found" } + end + end + end + + def create + @officer.user_id = params[:user_id] + @officer.save + + redirect_to admin_poll_officers_path + end + + def destroy + @officer.destroy + redirect_to admin_poll_officers_path + end +end \ No newline at end of file diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 515a54deb..39ab74b96 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -19,7 +19,7 @@ module AdminHelper private def namespace - controller.class.parent.name.downcase + controller.class.parent.name.downcase.gsub("::", "/") end end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 0dfce6d3e..0f1100137 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -38,6 +38,7 @@ module Abilities can [:search, :create, :index, :destroy], ::Moderator can [:search, :create, :index, :summary], ::Valuator can [:search, :create, :index, :destroy], ::Manager + can [:search, :create, :index, :destroy], ::Poll::Officer can :manage, Annotation diff --git a/app/models/poll.rb b/app/models/poll.rb new file mode 100644 index 000000000..d815cba49 --- /dev/null +++ b/app/models/poll.rb @@ -0,0 +1,2 @@ +class Poll < ActiveRecord::Base +end \ No newline at end of file diff --git a/app/models/poll/officer.rb b/app/models/poll/officer.rb new file mode 100644 index 000000000..d6fe5730a --- /dev/null +++ b/app/models/poll/officer.rb @@ -0,0 +1,8 @@ +class Poll + class Officer < ActiveRecord::Base + belongs_to :user + delegate :name, :email, to: :user + + validates :user_id, presence: true, uniqueness: true + end +end \ No newline at end of file diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 7ea48b2c6..40bcc6330 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -83,6 +83,12 @@ <% end %> +
  • > + <%= link_to admin_poll_officers_path do %> + <%= t('admin.menu.poll_officers') %> + <% end %> +
  • +
  • > <%= link_to admin_activity_path do %> <%= t('admin.menu.activity') %> diff --git a/app/views/admin/poll/_menu.html.erb b/app/views/admin/poll/_menu.html.erb new file mode 100644 index 000000000..08efd87dc --- /dev/null +++ b/app/views/admin/poll/_menu.html.erb @@ -0,0 +1 @@ +<%= render "admin/menu" %> \ No newline at end of file diff --git a/app/views/admin/poll/officers/_officer.html.erb b/app/views/admin/poll/officers/_officer.html.erb new file mode 100644 index 000000000..c9251548d --- /dev/null +++ b/app/views/admin/poll/officers/_officer.html.erb @@ -0,0 +1,26 @@ +
    + + + + + + + + +
    + <%= officer.name %> + + <%= officer.email %> + + <% if officer.persisted? %> + <%= link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(officer), + method: :delete, + class: "button hollow alert" %> + <% else %> + <%= link_to t('admin.poll_officers.officer.add'),{ controller: "admin/poll/officers", action: :create, user_id: officer.user_id }, + method: :post, + class: "button success" %> + <% end %> +
    +
    diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb new file mode 100644 index 000000000..c330741af --- /dev/null +++ b/app/views/admin/poll/officers/index.html.erb @@ -0,0 +1,46 @@ +

    <%= t("admin.poll_officers.index.title") %>

    + +
    + <%= form_tag search_admin_poll_officers_path, method: :get, remote: true do %> +
    + <%= text_field_tag :email, '', placeholder: t('admin.poll_officers.search.email_placeholder') %> +
    +
    + <%= submit_tag t('admin.poll_officers.search.search'), class: 'button' %> +
    + <% end %> +
    + +
    + +

    <%= page_entries_info @officers %>

    + + + <% @officers.each do |officer| %> + + + + + + <% end %> +
    + <%= officer.name %> + + <%= officer.email %> + + <% if officer.persisted? %> + <%= link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(officer), + method: :delete, + class: "button hollow alert" + %> + <% else %> + <%= link_to t('admin.poll_officers.officer.add'), + { controller: "admin/poll/officers", action: :create, + user_id: officer.user_id }, + method: :post, + class: "button success" %> + <% end %> +
    + +<%= paginate @officers %> diff --git a/app/views/admin/poll/officers/search.js.erb b/app/views/admin/poll/officers/search.js.erb new file mode 100644 index 000000000..bd259f7fb --- /dev/null +++ b/app/views/admin/poll/officers/search.js.erb @@ -0,0 +1 @@ +$("#search-result").html("<%= j render 'officer', officer: @officer %>"); diff --git a/app/views/admin/poll/officers/user_not_found.js.erb b/app/views/admin/poll/officers/user_not_found.js.erb new file mode 100644 index 000000000..108f75295 --- /dev/null +++ b/app/views/admin/poll/officers/user_not_found.js.erb @@ -0,0 +1 @@ +$("#search-result").html("
    <%= j t('admin.officers.search.user_not_found') %>
    "); diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 2f73f64d8..97723c9c8 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -105,6 +105,7 @@ en: managers: Managers moderators: Moderators valuators: Valuators + poll_officers: Poll officers officials: Officials organizations: Organisations settings: Configuration settings @@ -140,6 +141,16 @@ en: in_evaluation_count: In evaluation total_count: Total cost: Cost + poll_officers: + index: + title: Poll officers + officer: + add: Add + delete: Delete + search: + email_placeholder: Search user by email + search: Search + user_not_found: User not found officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 5aada1ce1..f71293208 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -103,6 +103,7 @@ es: managers: Gestores moderators: Moderadores valuators: Evaluadores + poll_officers: Presidentes de mesa officials: Cargos públicos organizations: Organizaciones settings: Configuración global @@ -138,6 +139,16 @@ es: in_evaluation_count: En evaluación total_count: Total cost: Coste total + poll_officers: + index: + title: Presidentes de mesa + officer: + add: Añadir como Presidente de mesa + delete: Borrar + search: + email_placeholder: Buscar usuario por email + search: Buscar + user_not_found: Usuario no encontrado officials: edit: destroy: Eliminar condición de 'Cargo Público' diff --git a/config/routes.rb b/config/routes.rb index df1a7c6fb..1821537e5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -179,6 +179,12 @@ Rails.application.routes.draw do get :search, on: :collection end + namespace :poll do + resources :officers, only: [:index, :create, :destroy] do + get :search, on: :collection + end + end + resources :verifications, controller: :verifications, only: :index do get :search, on: :collection end diff --git a/db/migrate/20160914110004_create_polls.rb b/db/migrate/20160914110004_create_polls.rb new file mode 100644 index 000000000..9dd67d9ba --- /dev/null +++ b/db/migrate/20160914110004_create_polls.rb @@ -0,0 +1,7 @@ +class CreatePolls < ActiveRecord::Migration + def change + create_table :polls do |t| + t.string :name + end + end +end diff --git a/db/migrate/20160914110039_create_poll_officers.rb b/db/migrate/20160914110039_create_poll_officers.rb new file mode 100644 index 000000000..329220d40 --- /dev/null +++ b/db/migrate/20160914110039_create_poll_officers.rb @@ -0,0 +1,7 @@ +class CreatePollOfficers < ActiveRecord::Migration + def change + create_table :poll_officers do |t| + t.integer :user_id + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a93942873..cfaf2a871 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -270,6 +270,14 @@ ActiveRecord::Schema.define(version: 20161102133838) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree + create_table "poll_officers", force: :cascade do |t| + t.integer "user_id" + end + + create_table "polls", force: :cascade do |t| + t.string "name" + end + create_table "proposal_notifications", force: :cascade do |t| t.string "title" t.text "body" diff --git a/spec/factories.rb b/spec/factories.rb index 13371a504..cd9b2c7fd 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -263,6 +263,10 @@ FactoryGirl.define do user end + factory :poll_officer, class: 'Poll::Officer' do + user + end + factory :organization do user responsible_name "Johnny Utah" diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb new file mode 100644 index 000000000..ed9ec545d --- /dev/null +++ b/spec/features/admin/poll/officers_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +feature 'Admin poll officers' do + background do + @admin = create(:administrator) + @user = create(:user, username: 'Pedro Jose Garcia') + @officer = create(:poll_officer) + login_as(@admin.user) + visit admin_poll_officers_path + end + + scenario 'Index' do + expect(page).to have_content @officer.name + expect(page).to have_content @officer.email + expect(page).to_not have_content @user.name + end + + scenario 'Create poll officer', :js do + fill_in 'email', with: @user.email + click_button 'Search' + + expect(page).to have_content @user.name + click_link 'Add' + within("#officers") do + expect(page).to have_content @user.name + end + end + + scenario 'Delete poll officer' do + click_link 'Delete' + + within("#officers") do + expect(page).to_not have_content @officer.name + end + end +end \ No newline at end of file From 08fbe745a80b078238d2ad702b90cf241c1754be Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 14 Sep 2016 14:25:38 +0200 Subject: [PATCH 068/523] fixes translation key --- app/views/admin/poll/officers/user_not_found.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/officers/user_not_found.js.erb b/app/views/admin/poll/officers/user_not_found.js.erb index 108f75295..40b6caac5 100644 --- a/app/views/admin/poll/officers/user_not_found.js.erb +++ b/app/views/admin/poll/officers/user_not_found.js.erb @@ -1 +1 @@ -$("#search-result").html("
    <%= j t('admin.officers.search.user_not_found') %>
    "); +$("#search-result").html("
    <%= j t('admin.poll_officers.search.user_not_found') %>
    "); From 503338e47b27079b2830fb0ddb8c5ab5adc4e9b8 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 16 Sep 2016 13:06:30 +0200 Subject: [PATCH 069/523] adds view placeholders for officing polls --- .../admin/poll/booths_controller.rb | 16 ++++++++++++++++ .../admin/poll/officers_controller.rb | 9 ++++++++- app/controllers/admin/poll/polls_controller.rb | 16 ++++++++++++++++ app/controllers/officing/base_controller.rb | 18 ++++++++++++++++++ .../officing/dashboard_controller.rb | 6 ++++++ app/controllers/officing/results_controller.rb | 15 +++++++++++++++ app/controllers/officing/voters_controller.rb | 9 +++++++++ app/views/admin/_menu.html.erb | 16 ++++++++++++++-- app/views/admin/poll/booths/edit.html.erb | 1 + app/views/admin/poll/booths/index.html.erb | 1 + app/views/admin/poll/booths/new.html.erb | 1 + app/views/admin/poll/booths/show.html.erb | 1 + app/views/admin/poll/officers/edit.html.erb | 1 + app/views/admin/poll/officers/show.html.erb | 1 + app/views/admin/poll/polls/edit.html.erb | 1 + app/views/admin/poll/polls/index.html.erb | 1 + app/views/admin/poll/polls/new.html.erb | 1 + app/views/admin/poll/polls/show.html.erb | 1 + app/views/officing/_menu.html.erb | 18 ++++++++++++++++++ app/views/officing/dashboard/index.html.erb | 6 ++++++ app/views/officing/results/index.html.erb | 1 + app/views/officing/results/new.html.erb | 1 + app/views/officing/results/show.html.erb | 1 + app/views/officing/voters/new.html.erb | 1 + app/views/officing/voters/show.html.erb | 1 + app/views/poll/voters/new.html.erb | 1 + app/views/shared/_admin_login_items.html.erb | 6 ++++++ config/locales/admin.en.yml | 2 ++ config/locales/admin.es.yml | 2 ++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/officing.en.yml | 10 ++++++++++ config/locales/officing.es.yml | 10 ++++++++++ config/routes.rb | 17 ++++++++++++++--- 34 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 app/controllers/admin/poll/booths_controller.rb create mode 100644 app/controllers/admin/poll/polls_controller.rb create mode 100644 app/controllers/officing/base_controller.rb create mode 100644 app/controllers/officing/dashboard_controller.rb create mode 100644 app/controllers/officing/results_controller.rb create mode 100644 app/controllers/officing/voters_controller.rb create mode 100644 app/views/admin/poll/booths/edit.html.erb create mode 100644 app/views/admin/poll/booths/index.html.erb create mode 100644 app/views/admin/poll/booths/new.html.erb create mode 100644 app/views/admin/poll/booths/show.html.erb create mode 100644 app/views/admin/poll/officers/edit.html.erb create mode 100644 app/views/admin/poll/officers/show.html.erb create mode 100644 app/views/admin/poll/polls/edit.html.erb create mode 100644 app/views/admin/poll/polls/index.html.erb create mode 100644 app/views/admin/poll/polls/new.html.erb create mode 100644 app/views/admin/poll/polls/show.html.erb create mode 100644 app/views/officing/_menu.html.erb create mode 100644 app/views/officing/dashboard/index.html.erb create mode 100644 app/views/officing/results/index.html.erb create mode 100644 app/views/officing/results/new.html.erb create mode 100644 app/views/officing/results/show.html.erb create mode 100644 app/views/officing/voters/new.html.erb create mode 100644 app/views/officing/voters/show.html.erb create mode 100644 app/views/poll/voters/new.html.erb create mode 100644 config/locales/officing.en.yml create mode 100644 config/locales/officing.es.yml diff --git a/app/controllers/admin/poll/booths_controller.rb b/app/controllers/admin/poll/booths_controller.rb new file mode 100644 index 000000000..9b1e62f8f --- /dev/null +++ b/app/controllers/admin/poll/booths_controller.rb @@ -0,0 +1,16 @@ +class Admin::Poll::BoothsController < Admin::BaseController + skip_authorization_check + + def index + end + + def show + end + + def new + end + + def edit + end + +end \ No newline at end of file diff --git a/app/controllers/admin/poll/officers_controller.rb b/app/controllers/admin/poll/officers_controller.rb index 5495d390c..7f6f918d7 100644 --- a/app/controllers/admin/poll/officers_controller.rb +++ b/app/controllers/admin/poll/officers_controller.rb @@ -1,5 +1,5 @@ class Admin::Poll::OfficersController < Admin::BaseController - load_and_authorize_resource :officer, class: "Poll::Officer" + load_and_authorize_resource :officer, class: "Poll::Officer", except: [:edit, :show] def index @officers = @officers.page(params[:page]) @@ -29,4 +29,11 @@ class Admin::Poll::OfficersController < Admin::BaseController @officer.destroy redirect_to admin_poll_officers_path end + + def show + end + + def edit + end + end \ No newline at end of file diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb new file mode 100644 index 000000000..b90fd2c11 --- /dev/null +++ b/app/controllers/admin/poll/polls_controller.rb @@ -0,0 +1,16 @@ +class Admin::Poll::PollsController < Admin::BaseController + skip_authorization_check + + def index + end + + def show + end + + def new + end + + def edit + end + +end \ No newline at end of file diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb new file mode 100644 index 000000000..5aeb2431c --- /dev/null +++ b/app/controllers/officing/base_controller.rb @@ -0,0 +1,18 @@ +class Officing::BaseController < ActionController::Base + layout 'admin' + + #before_action :verify_officer + before_action :set_locale + + private + + def set_locale + if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym) + session[:locale] = params[:locale] + end + + session[:locale] ||= I18n.default_locale + + I18n.locale = session[:locale] + end +end \ No newline at end of file diff --git a/app/controllers/officing/dashboard_controller.rb b/app/controllers/officing/dashboard_controller.rb new file mode 100644 index 000000000..4d80a974a --- /dev/null +++ b/app/controllers/officing/dashboard_controller.rb @@ -0,0 +1,6 @@ +class Officing::DashboardController < Officing::BaseController + + def index + end + +end diff --git a/app/controllers/officing/results_controller.rb b/app/controllers/officing/results_controller.rb new file mode 100644 index 000000000..03e638366 --- /dev/null +++ b/app/controllers/officing/results_controller.rb @@ -0,0 +1,15 @@ +class Officing::ResultsController < Officing::BaseController + layout 'admin' + + before_action :authenticate_user! + + def index + end + + def show + end + + def new + end + +end \ No newline at end of file diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb new file mode 100644 index 000000000..6d7ad8512 --- /dev/null +++ b/app/controllers/officing/voters_controller.rb @@ -0,0 +1,9 @@ +class Officing::VotersController < Officing::BaseController + layout 'admin' + + before_action :authenticate_user! + + def new + end + +end \ No newline at end of file diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 40bcc6330..48736c378 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -83,12 +83,24 @@ <% end %>
  • -
  • > - <%= link_to admin_poll_officers_path do %> +
  • > + <%= link_to admin_poll_officers_path(Poll.last) do %> <%= t('admin.menu.poll_officers') %> <% end %>
  • +
  • > + <%= link_to admin_polls_path do %> + <%= t('admin.menu.polls') %> + <% end %> +
  • + +
  • > + <%= link_to admin_poll_booths_url(Poll.last) do %> + <%= t('admin.menu.booths') %> + <% end %> +
  • +
  • > <%= link_to admin_activity_path do %> <%= t('admin.menu.activity') %> diff --git a/app/views/admin/poll/booths/edit.html.erb b/app/views/admin/poll/booths/edit.html.erb new file mode 100644 index 000000000..4f66c61cd --- /dev/null +++ b/app/views/admin/poll/booths/edit.html.erb @@ -0,0 +1 @@ +booth edit \ No newline at end of file diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb new file mode 100644 index 000000000..7ef71767d --- /dev/null +++ b/app/views/admin/poll/booths/index.html.erb @@ -0,0 +1 @@ +booth index \ No newline at end of file diff --git a/app/views/admin/poll/booths/new.html.erb b/app/views/admin/poll/booths/new.html.erb new file mode 100644 index 000000000..ebcb88bd4 --- /dev/null +++ b/app/views/admin/poll/booths/new.html.erb @@ -0,0 +1 @@ +booth new \ No newline at end of file diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb new file mode 100644 index 000000000..791a97e48 --- /dev/null +++ b/app/views/admin/poll/booths/show.html.erb @@ -0,0 +1 @@ +booth show \ No newline at end of file diff --git a/app/views/admin/poll/officers/edit.html.erb b/app/views/admin/poll/officers/edit.html.erb new file mode 100644 index 000000000..5c64d3aeb --- /dev/null +++ b/app/views/admin/poll/officers/edit.html.erb @@ -0,0 +1 @@ +officer edit \ No newline at end of file diff --git a/app/views/admin/poll/officers/show.html.erb b/app/views/admin/poll/officers/show.html.erb new file mode 100644 index 000000000..fc702276e --- /dev/null +++ b/app/views/admin/poll/officers/show.html.erb @@ -0,0 +1 @@ +officer show \ No newline at end of file diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb new file mode 100644 index 000000000..ca0a8dc14 --- /dev/null +++ b/app/views/admin/poll/polls/edit.html.erb @@ -0,0 +1 @@ +poll edit \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb new file mode 100644 index 000000000..d01cf64f1 --- /dev/null +++ b/app/views/admin/poll/polls/index.html.erb @@ -0,0 +1 @@ +polls index \ No newline at end of file diff --git a/app/views/admin/poll/polls/new.html.erb b/app/views/admin/poll/polls/new.html.erb new file mode 100644 index 000000000..6e11970d3 --- /dev/null +++ b/app/views/admin/poll/polls/new.html.erb @@ -0,0 +1 @@ +poll new \ No newline at end of file diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb new file mode 100644 index 000000000..61c9d5afb --- /dev/null +++ b/app/views/admin/poll/polls/show.html.erb @@ -0,0 +1 @@ +poll show \ No newline at end of file diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb new file mode 100644 index 000000000..81734d99f --- /dev/null +++ b/app/views/officing/_menu.html.erb @@ -0,0 +1,18 @@ +
    +
      + +
    • > + <%= link_to new_officing_poll_voter_path(Poll.last) do %> + + <%= t("officing.menu.voters") %> + <% end %> +
    • + +
    • > + <%= link_to new_officing_poll_result_path(Poll.last) do %> + + <%= t("officing.menu.results") %> + <% end %> +
    • + +
    diff --git a/app/views/officing/dashboard/index.html.erb b/app/views/officing/dashboard/index.html.erb new file mode 100644 index 000000000..cf014d719 --- /dev/null +++ b/app/views/officing/dashboard/index.html.erb @@ -0,0 +1,6 @@ +
    +

    <%= t("officing.dashboard.index.title") %>

    + +

    <%= t("officing.dashboard.index.info") %>

    + +
    diff --git a/app/views/officing/results/index.html.erb b/app/views/officing/results/index.html.erb new file mode 100644 index 000000000..8e9faa1ab --- /dev/null +++ b/app/views/officing/results/index.html.erb @@ -0,0 +1 @@ +results index \ No newline at end of file diff --git a/app/views/officing/results/new.html.erb b/app/views/officing/results/new.html.erb new file mode 100644 index 000000000..bb40dff9e --- /dev/null +++ b/app/views/officing/results/new.html.erb @@ -0,0 +1 @@ +results new \ No newline at end of file diff --git a/app/views/officing/results/show.html.erb b/app/views/officing/results/show.html.erb new file mode 100644 index 000000000..b3ca8e29c --- /dev/null +++ b/app/views/officing/results/show.html.erb @@ -0,0 +1 @@ +results show \ No newline at end of file diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb new file mode 100644 index 000000000..0fb4c6bc3 --- /dev/null +++ b/app/views/officing/voters/new.html.erb @@ -0,0 +1 @@ +voters new diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb new file mode 100644 index 000000000..fd8c83123 --- /dev/null +++ b/app/views/officing/voters/show.html.erb @@ -0,0 +1 @@ +voters show \ No newline at end of file diff --git a/app/views/poll/voters/new.html.erb b/app/views/poll/voters/new.html.erb new file mode 100644 index 000000000..596b8769c --- /dev/null +++ b/app/views/poll/voters/new.html.erb @@ -0,0 +1 @@ +new.html.erb \ No newline at end of file diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 6ba10bbca..cfe3cc1c9 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -22,4 +22,10 @@ <%= link_to t("layouts.header.management"), management_sign_in_path %>
  • <% end %> + + <%# if current_user.administrator? || current_user.officer? %> +
  • + <%= link_to t("layouts.header.officing"), officing_root_path %> +
  • + <%# end %> <% end %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 97723c9c8..a04595e8b 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -106,6 +106,8 @@ en: moderators: Moderators valuators: Valuators poll_officers: Poll officers + polls: Polls + booths: Booths officials: Officials organizations: Organisations settings: Configuration settings diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index f71293208..ba3548215 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -104,6 +104,8 @@ es: moderators: Moderadores valuators: Evaluadores poll_officers: Presidentes de mesa + polls: Votaciones + booths: Urnas officials: Cargos públicos organizations: Organizaciones settings: Configuración global diff --git a/config/locales/en.yml b/config/locales/en.yml index 233ebf735..9230ecbf8 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -195,6 +195,7 @@ en: management: Management moderation: Moderation valuation: Valuation + officing: Polling officers more_information: More information my_account_link: My account my_activity_link: My activity diff --git a/config/locales/es.yml b/config/locales/es.yml index 54aa483cd..80541466b 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -195,6 +195,7 @@ es: management: Gestión moderation: Moderar valuation: Evaluación + officing: Presidentes de mesa more_information: Más información my_account_link: Mi cuenta my_activity_link: Mi actividad diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml new file mode 100644 index 000000000..532d18498 --- /dev/null +++ b/config/locales/officing.en.yml @@ -0,0 +1,10 @@ +--- +en: + officing: + dashboard: + index: + title: Poll officing + info: Here you can validate user documents and store voting results + menu: + voters: Validate citizen document + results: Store voting results \ No newline at end of file diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml new file mode 100644 index 000000000..baa60b106 --- /dev/null +++ b/config/locales/officing.es.yml @@ -0,0 +1,10 @@ +--- +es: + officing: + dashboard: + index: + title: Presidir mesa de votaciones + info: Aquí puedes validar documentos de ciudadanos y guardar los resultados de las urnas + menu: + voters: Validar documento de identidad + results: Guardar resultados de la votación \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1821537e5..2b223b46b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -179,9 +179,12 @@ Rails.application.routes.draw do get :search, on: :collection end - namespace :poll do - resources :officers, only: [:index, :create, :destroy] do - get :search, on: :collection + scope module: 'poll' do + resources :polls do + resources :booths + resources :officers do + get :search, on: :collection + end end end @@ -268,6 +271,14 @@ Rails.application.routes.draw do end end + namespace :officing do + resources :polls do + resources :voters, only: [:new, :show] + resources :results, only: [:new, :index, :show] + end + root to: "dashboard#index" + end + if Rails.env.development? mount LetterOpenerWeb::Engine, at: "/letter_opener" end From 00721bac127ee3e089839c540a7b29d6abe29c6a Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 16 Sep 2016 13:06:39 +0200 Subject: [PATCH 070/523] updates dev_seeds with polls --- db/dev_seeds.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 230cd0196..d3d9749b3 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -358,3 +358,9 @@ Proposal.last(3).each do |proposal| created_at: rand((Time.now - 1.week) .. Time.now)) puts " #{banner.title}" end + +puts "Creating polls" + +3.times.each_with_index do |i| + Poll.create(name: "Poll #{i}") +end \ No newline at end of file From 2acd1a69cd483fa86c7edb24af1b053d1e3204ec Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Sep 2016 19:07:12 +0200 Subject: [PATCH 071/523] Adds i18n and styles to admin polls index and new --- app/views/admin/poll/polls/index.html.erb | 37 ++++++++++++++++++++++- app/views/admin/poll/polls/new.html.erb | 37 ++++++++++++++++++++++- config/locales/admin.en.yml | 15 +++++++++ config/locales/admin.es.yml | 15 +++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index d01cf64f1..8ba763356 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -1 +1,36 @@ -polls index \ No newline at end of file +

    <%= t("admin.polls.index.title") %>

    + +<%= link_to t("admin.polls.index.create"), new_admin_poll_path, class: "button success float-right" %> + + +
    + <%= t("admin.polls.index.no_polls") %> +
    + + + + + + + + + + + + + + + + + + +
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %> 
    + + <%= link_to "Votación de propuestas 2016", "#" %> + + + Próximamente +
    (15/12/2016 - 15/02/2017) +
    + <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> +
    diff --git a/app/views/admin/poll/polls/new.html.erb b/app/views/admin/poll/polls/new.html.erb index 6e11970d3..b2d74cffc 100644 --- a/app/views/admin/poll/polls/new.html.erb +++ b/app/views/admin/poll/polls/new.html.erb @@ -1 +1,36 @@ -poll new \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.polls.new.title") %>

    + +
    +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + +
    +
    + +
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index a04595e8b..9e267714d 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -9,6 +9,7 @@ en: restore: Restore mark_featured: Featured unmark_featured: Unmark featured + edit: Edit banners: index: title: Banners @@ -153,6 +154,20 @@ en: email_placeholder: Search user by email search: Search user_not_found: User not found + polls: + index: + title: "List of polls" + no_polls: "There are any poll." + create: "Create poll" + name: "Name" + status: "Status" + new: + title: "New poll" + name: "Name" + reference: "Reference number" + open_date: "Open date" + close_date: "Close date" + submit_button: "Create poll" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index ba3548215..a711be773 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -9,6 +9,7 @@ es: restore: Volver a mostrar mark_featured: Destacar unmark_featured: Quitar destacado + edit: Editar banners: index: title: Banners @@ -151,6 +152,20 @@ es: email_placeholder: Buscar usuario por email search: Buscar user_not_found: Usuario no encontrado + polls: + index: + title: "Listado de votaciones" + no_polls: "No hay ninguna votación." + create: "Crear votación" + name: "Nombre" + status: "Estado" + new: + title: "Nueva votación" + name: "Nombre" + reference: "Número de referencia" + open_date: "Fecha de apertura" + close_date: "Fecha de cierre" + submit_button: "Crear votación" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 7b24e73999bbe5bbb9509848ad4b33d31cb196e9 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 19 Sep 2016 13:36:42 +0200 Subject: [PATCH 072/523] Adds content to edit and show views --- app/views/admin/poll/polls/edit.html.erb | 37 +++++++++++++++++++- app/views/admin/poll/polls/index.html.erb | 6 ++-- app/views/admin/poll/polls/show.html.erb | 42 ++++++++++++++++++++++- config/locales/admin.en.yml | 15 ++++++-- config/locales/admin.es.yml | 13 +++++++ 5 files changed, 106 insertions(+), 7 deletions(-) diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb index ca0a8dc14..68eb7cc3b 100644 --- a/app/views/admin/poll/polls/edit.html.erb +++ b/app/views/admin/poll/polls/edit.html.erb @@ -1 +1,36 @@ -poll edit \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.polls.edit.title") %>

    + +
    +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + +
    +
    + +
    \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 8ba763356..2f7744c97 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -7,7 +7,7 @@ <%= t("admin.polls.index.no_polls") %>
    - + @@ -20,7 +20,7 @@ diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 61c9d5afb..9b4971214 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -1 +1,41 @@ -poll show \ No newline at end of file +<%= render "shared/back_link" %> +
    + +

    Votación de propuestas 2016

    +<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +

    (REFNUM)

    +

    Próximamente (15/12/2016 - 15/02/2017)

    +<%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> + + +
    + <%= t("admin.polls.show.no_booths") %> +
    + + +

    <%= t("admin.polls.show.booths_title") %>

    + +
    - <%= link_to "Votación de propuestas 2016", "#" %> + <%= link_to "Votación de propuestas 2016 (REFNUM)", "3" %> @@ -28,7 +28,7 @@
    (15/12/2016 - 15/02/2017)
    - <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> + <%= link_to t("admin.actions.edit"), "3/edit", class: "button hollow" %>
    + + + + + + + + + + + + + + +
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> 
    + + <%= link_to "Urna Moncloa (REFNUM)", "#" %> + + + C/ Isaac Peral, 25. 28003, Madrid + + <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> +
    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 9e267714d..1141aedf3 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -33,8 +33,6 @@ en: editing: Edit banner form: submit_button: Save changes - errors: - form: errors: form: error: @@ -168,6 +166,19 @@ en: open_date: "Open date" close_date: "Close date" submit_button: "Create poll" + edit: + title: "Edit poll" + name: "Name" + reference: "Reference number" + open_date: "Open date" + close_date: "Close date" + submit_button: "Update poll" + show: + no_booths: "There is no booths in this poll." + add_booth: "Add booth" + booths_title: "List of booths" + name: "Name" + location: "Location" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index a711be773..de22029e0 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -166,6 +166,19 @@ es: open_date: "Fecha de apertura" close_date: "Fecha de cierre" submit_button: "Crear votación" + edit: + title: "Editar votación" + name: "Nombre" + reference: "Número de referencia" + open_date: "Fecha de apertura" + close_date: "Fecha de cierre" + submit_button: "Actualizar votación" + show: + no_booths: "No hay urnas en esta votación." + add_booth: "Añadir urna" + booths_title: "Listado de urnas" + name: "Nombre" + location: "Ubicación" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 5d2a9bead3186909273e8418293021b73b9ca2f4 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 17:25:51 +0200 Subject: [PATCH 073/523] hot fix to load last poll on officer's index --- app/views/admin/poll/officers/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index c330741af..56daabb94 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -27,7 +27,7 @@ <% if officer.persisted? %> <%= link_to t('admin.poll_officers.officer.delete'), - admin_poll_officer_path(officer), + admin_poll_officer_path(Poll.last, officer), method: :delete, class: "button hollow alert" %> From faecb510544ad83735f8961728c6f226bd236dfc Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 19 Sep 2016 17:26:48 +0200 Subject: [PATCH 074/523] Adds booths index content --- app/views/admin/poll/booths/index.html.erb | 45 +++++++++++++++++++++- config/locales/admin.en.yml | 9 +++++ config/locales/admin.es.yml | 9 +++++ 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 7ef71767d..3af66c042 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -1 +1,44 @@ -booth index \ No newline at end of file +

    <%= t("admin.booths.index.title") %>

    + +
    +
    + +
    +
    + +

    <%= t("admin.booths.index.title_list") %>

    + + +
    + <%= t("admin.booths.index.no_booths") %> +
    + + + + + + + + + + + + + + + + + + +
    <%= t("admin.booths.index.name") %><%= t("admin.booths.index.location") %> 
    + + <%= link_to "Urna Moncloa (REFNUM)", "#" %> + + + C/ Isaac Peral, 25. 28003, Madrid + + <%= link_to t("admin.actions.edit"), "/edit", class: "button hollow" %> + <%= link_to t("admin.booths.index.add_officer"), "/edit", class: "button success" %> +
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 1141aedf3..4c058992d 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -179,6 +179,15 @@ en: booths_title: "List of booths" name: "Name" location: "Location" + booths: + index: + title: "List of booths" + select_poll: "Select a poll" + title_list: "List of booths of poll %{poll}" + no_booths: "There is no booths in this poll." + name: "Name" + location: "Location" + add_officer: "Add officer" officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index de22029e0..22fef3006 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -179,6 +179,15 @@ es: booths_title: "Listado de urnas" name: "Nombre" location: "Ubicación" + booths: + index: + title: "Lista de urnas" + select_poll: "Selecciona una votación" + title_list: "Lista de urnas de la votación %{poll}" + no_booths: "No hay urnas en esta votación." + name: "Nombre" + location: "Ubicación" + add_officer: "Añadir presidente" officials: edit: destroy: Eliminar condición de 'Cargo Público' From 7f0d233bce1f782220e9dd6749008a300ab80468 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 19 Sep 2016 18:32:21 +0200 Subject: [PATCH 075/523] Add views for admin booths --- app/views/admin/poll/booths/edit.html.erb | 29 ++++++++++++++- app/views/admin/poll/booths/index.html.erb | 9 ++--- app/views/admin/poll/booths/new.html.erb | 29 ++++++++++++++- app/views/admin/poll/booths/show.html.erb | 41 +++++++++++++++++++++- app/views/admin/poll/polls/index.html.erb | 4 +-- config/locales/admin.en.yml | 20 +++++++++++ config/locales/admin.es.yml | 13 +++++++ 7 files changed, 136 insertions(+), 9 deletions(-) diff --git a/app/views/admin/poll/booths/edit.html.erb b/app/views/admin/poll/booths/edit.html.erb index 4f66c61cd..e48db9cdd 100644 --- a/app/views/admin/poll/booths/edit.html.erb +++ b/app/views/admin/poll/booths/edit.html.erb @@ -1 +1,28 @@ -booth edit \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.booths.edit.title") %>: <%= t("admin.booths.edit.subtitle") %>

    + +
    +
    +
    + + +
    + +
    + + +
    + +
    + + "> +
    +
    + +
    +
    + +
    +
    +
    diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 3af66c042..2e9a2f70b 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -14,8 +14,9 @@
    <%= t("admin.booths.index.no_booths") %>
    + - +<%= link_to t("admin.booths.index.add_booth"), new_admin_poll_booth_path, class: "button success" %> @@ -35,10 +36,10 @@ C/ Isaac Peral, 25. 28003, Madrid -
    - <%= link_to t("admin.actions.edit"), "/edit", class: "button hollow" %> - <%= link_to t("admin.booths.index.add_officer"), "/edit", class: "button success" %> + <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> + <%= link_to t("admin.booths.index.add_officer"), "#", class: "button success" %>
    \ No newline at end of file + diff --git a/app/views/admin/poll/booths/new.html.erb b/app/views/admin/poll/booths/new.html.erb index ebcb88bd4..e83d2f47c 100644 --- a/app/views/admin/poll/booths/new.html.erb +++ b/app/views/admin/poll/booths/new.html.erb @@ -1 +1,28 @@ -booth new \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("admin.booths.new.title") %>: <%= t("admin.booths.new.subtitle") %>

    + +
    +
    +
    + + +
    + +
    + + +
    + +
    + + "> +
    +
    + +
    +
    + +
    +
    +
    diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 791a97e48..8a5c2fd99 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -1 +1,40 @@ -booth show \ No newline at end of file +<%= render 'shared/back_link' %> +
    + +

    Urna Moncloa (REFNUM)

    +<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> + +

    <%= t("admin.booths.show.location") %>: C/ Isaac Peral, 25. 28003, Madrid

    + +

    <%= t("admin.booths.show.officers_list") %>

    + + +
    + <%= t("admin.booths.show.no_officers") %> +
    + + +<%= link_to t("admin.booths.show.add_officer"), "#", class: "button success" %> + + + <%# @officers.each do |officer| %> + + + + + + <%# end %> +
    + <%# officer.name %> + Admin + + admin@consul.dev + <%# officer.email %> + + <%= link_to t('admin.poll_officers.officer.delete'), "#", class: "button hollow alert" %> + <%# link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(Poll.last, officer), + method: :delete, + class: "button hollow alert" + %> +
    \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 2f7744c97..c260ab255 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -20,7 +20,7 @@ - <%= link_to "Votación de propuestas 2016 (REFNUM)", "3" %> + <%= link_to "Votación de propuestas 2016 (REFNUM)", "polls/3" %> @@ -28,7 +28,7 @@
    (15/12/2016 - 15/02/2017) - <%= link_to t("admin.actions.edit"), "3/edit", class: "button hollow" %> + <%= link_to t("admin.actions.edit"), "polls/3/edit", class: "button hollow" %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 4c058992d..40822778f 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -185,9 +185,29 @@ en: select_poll: "Select a poll" title_list: "List of booths of poll %{poll}" no_booths: "There is no booths in this poll." + add_booth: "Add booth" name: "Name" location: "Location" add_officer: "Add officer" + new: + title: "Poll %{poll}" + subtitle: "New booth" + name: "Name" + reference: "Reference number" + location: "Location" + submit_button: "Create booth" + edit: + title: "Poll %{poll}" + subtitle: "Edit booth" + name: "Name" + reference: "Reference number" + location: "Location" + submit_button: "Update booth" + show: + location: "Location" + add_officer: "Add officer" + officers_list: "List of officers" + no_officers: "There is no officers in this booth." officials: edit: destroy: Remove 'Official' status diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 22fef3006..4c807e454 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -185,9 +185,22 @@ es: select_poll: "Selecciona una votación" title_list: "Lista de urnas de la votación %{poll}" no_booths: "No hay urnas en esta votación." + add_booth: "Añadir urna" name: "Nombre" location: "Ubicación" add_officer: "Añadir presidente" + new: + title: "Votación %{poll}" + subtitle: "Nueva urna" + name: "Nombre" + reference: "Número de referencia" + location: "Ubicación" + submit_button: "Crear urna" + show: + location: "Ubicación" + add_officer: "Añadir presidente de mesa" + officers_list: "Lista de presidentes de mesa" + no_officers: "No hay presidentes de mesa en esta urna." officials: edit: destroy: Eliminar condición de 'Cargo Público' From 44df91346adc489980132f3233eb27995f32f9e2 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 13:31:18 +0200 Subject: [PATCH 076/523] validates voter in census --- app/models/poll/voter.rb | 15 ++++++ config/locales/activerecord.en.yml | 4 ++ config/locales/activerecord.es.yml | 4 ++ .../20160914172016_create_poll_voters.rb | 9 ++++ db/schema.rb | 17 +++++++ lib/census_api.rb | 18 +++++-- spec/factories.rb | 23 +++++++++ spec/models/poll/voter_spec.rb | 47 +++++++++++++++++++ 8 files changed, 134 insertions(+), 3 deletions(-) create mode 100644 app/models/poll/voter.rb create mode 100644 db/migrate/20160914172016_create_poll_voters.rb create mode 100644 spec/models/poll/voter_spec.rb diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb new file mode 100644 index 000000000..92df28443 --- /dev/null +++ b/app/models/poll/voter.rb @@ -0,0 +1,15 @@ +class Poll + class Voter < ActiveRecord::Base + belongs_to :booth + + validate :in_census + + def in_census + errors.add(:document_number, :not_in_census) unless census_api_response.valid? + end + + def census_api_response + CensusApi.new.call(document_type, document_number) + end + end +end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 7de5b340e..2633a6d77 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -83,6 +83,10 @@ en: attributes: max_per_day: invalid: "You have reached the maximum number of private messages per day" + poll/voter: + attributes: + document_number: + not_in_census: "Document not in census" proposal: attributes: tag_list: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 4dae4cb56..10e53466d 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -83,6 +83,10 @@ es: attributes: max_per_day: invalid: "Has llegado al número máximo de mensajes privados por día" + poll/voter: + attributes: + document_number: + not_in_census: "Este documento no aparece en el censo" proposal: attributes: tag_list: diff --git a/db/migrate/20160914172016_create_poll_voters.rb b/db/migrate/20160914172016_create_poll_voters.rb new file mode 100644 index 000000000..df5bb4585 --- /dev/null +++ b/db/migrate/20160914172016_create_poll_voters.rb @@ -0,0 +1,9 @@ +class CreatePollVoters < ActiveRecord::Migration + def change + create_table :poll_voters do |t| + t.integer :booth_id + t.string :document_number + t.string :document_type + end + end +end diff --git a/db/schema.rb b/db/schema.rb index cfaf2a871..0453b852d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -270,10 +270,27 @@ ActiveRecord::Schema.define(version: 20161102133838) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree +<<<<<<< HEAD +======= + create_table "poll_booths", force: :cascade do |t| + t.string "name" + t.integer "poll_id" + end + +>>>>>>> validates voter in census create_table "poll_officers", force: :cascade do |t| t.integer "user_id" end +<<<<<<< HEAD +======= + create_table "poll_voters", force: :cascade do |t| + t.integer "booth_id" + t.string "document_number" + t.string "document_type" + end + +>>>>>>> validates voter in census create_table "polls", force: :cascade do |t| t.string "name" end diff --git a/lib/census_api.rb b/lib/census_api.rb index 678a748c6..d80f420e7 100644 --- a/lib/census_api.rb +++ b/lib/census_api.rb @@ -74,7 +74,7 @@ class CensusApi if end_point_available? client.call(:get_habita_datos, message: request(document_type, document_number)).body else - stubbed_response_body + stubbed_response(document_type, document_number) end end @@ -97,8 +97,20 @@ class CensusApi Rails.env.staging? || Rails.env.preproduction? || Rails.env.production? end - def stubbed_response_body - {get_habita_datos_response: {get_habita_datos_return: {hay_errores: false, datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} + def stubbed_response(document_type, document_number) + if document_number == "12345678Z" && document_type == "1" + stubbed_valid_response + else + stubbed_invalid_response + end + end + + def stubbed_valid_response + {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} + end + + def stubbed_invalid_response + {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {}, datos_vivienda: {}}}} end def is_dni?(document_type) diff --git a/spec/factories.rb b/spec/factories.rb index cd9b2c7fd..d29423aa1 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -263,10 +263,33 @@ FactoryGirl.define do user end + factory :poll do + sequence(:name) { |n| "Poll #{n}" } + end + factory :poll_officer, class: 'Poll::Officer' do user end + factory :poll_booth, class: 'Poll::Booth' do + sequence(:name) { |n| "Booth #{n}" } + poll + end + + factory :poll_voter, class: 'Poll::Voter' do + association :booth, factory: :budget_booth + trait :valid_document do + document_type "1" + document_number "12345678Z" + end + + trait :invalid_document do + document_type "1" + document_number "99999999A" + end + end + +>>>>>>> validates voter in census factory :organization do user responsible_name "Johnny Utah" diff --git a/spec/models/poll/voter_spec.rb b/spec/models/poll/voter_spec.rb new file mode 100644 index 000000000..de4536243 --- /dev/null +++ b/spec/models/poll/voter_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +describe :voter do + + let(:poll) { create(:poll) } + let(:booth) { create(:poll_booth, poll: poll) } + + describe "validations" do + + it "should be valid if in census and has not voted" do + voter = build(:poll_voter, :valid_document, booth: booth) + + expect(voter).to be_valid + end + + it "should not be valid if the user is not in the census" do + voter = build(:poll_voter, :invalid_document, booth: booth) + + expect(voter).to_not be_valid + expect(voter.errors.messages[:document_number]).to eq(["Document not in census"]) + end + + it "should not be valid if the user has already voted in the same booth" do + voter1 = create(:poll_voter, :valid_document, booth: booth) + voter2 = build(:poll_voter, :valid_document, booth: booth) + + expect(voter2).to_not be_valid + expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) + end + + it "should not be valid if the user has already voted in another booth" do + booth1 = create(:poll_booth, poll: poll) + booth2 = create(:poll_booth, poll: poll) + + voter1 = create(:poll_voter, :valid_document, booth: booth1) + voter2 = build(:poll_voter, :valid_document, booth: booth2) + + expect(voter2).to_not be_valid + expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) + end + + xit "should not be valid if the user has voted via web" do + pending "Implementation for voting via web" + end + + end +end \ No newline at end of file From 8dc7285681495646c2a08c141a42fac3a31afca2 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:22:35 +0200 Subject: [PATCH 077/523] validates user has not already voted --- app/models/poll.rb | 4 +++- app/models/poll/booth.rb | 6 ++++++ app/models/poll/voter.rb | 11 +++++++++++ config/locales/activerecord.en.yml | 1 + config/locales/activerecord.es.yml | 1 + db/migrate/20160914172535_create_poll_booths.rb | 8 ++++++++ 6 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 app/models/poll/booth.rb create mode 100644 db/migrate/20160914172535_create_poll_booths.rb diff --git a/app/models/poll.rb b/app/models/poll.rb index d815cba49..5a429c49d 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,2 +1,4 @@ class Poll < ActiveRecord::Base -end \ No newline at end of file + has_many :booths + has_many :voters, through: :booths, class_name: "Poll::Voter" +end diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb new file mode 100644 index 000000000..a05f3d547 --- /dev/null +++ b/app/models/poll/booth.rb @@ -0,0 +1,6 @@ +class Poll + class Booth < ActiveRecord::Base + belongs_to :poll + has_many :voters + end +end \ No newline at end of file diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 92df28443..353d593b3 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,15 +1,26 @@ class Poll class Voter < ActiveRecord::Base belongs_to :booth + delegate :poll, to: :booth validate :in_census + validate :has_not_voted def in_census errors.add(:document_number, :not_in_census) unless census_api_response.valid? end + def has_not_voted + errors.add(:document_number, :has_voted) if has_voted? + end + def census_api_response CensusApi.new.call(document_type, document_number) end + + def has_voted? + poll.voters.where(document_number: document_number, document_type: document_type).present? + end + end end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 2633a6d77..b719885b5 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -87,6 +87,7 @@ en: attributes: document_number: not_in_census: "Document not in census" + has_voted: "Has already voted" proposal: attributes: tag_list: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 10e53466d..9d51505fe 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -87,6 +87,7 @@ es: attributes: document_number: not_in_census: "Este documento no aparece en el censo" + has_voted: "Ya ha votado" proposal: attributes: tag_list: diff --git a/db/migrate/20160914172535_create_poll_booths.rb b/db/migrate/20160914172535_create_poll_booths.rb new file mode 100644 index 000000000..a474aba49 --- /dev/null +++ b/db/migrate/20160914172535_create_poll_booths.rb @@ -0,0 +1,8 @@ +class CreatePollBooths < ActiveRecord::Migration + def change + create_table :poll_booths do |t| + t.string :name + t.integer :poll_id + end + end +end From b54aee5702aeffa532867958157372e9f9b3baca Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:37:37 +0200 Subject: [PATCH 078/523] displays voter name if already voted --- app/models/poll/voter.rb | 8 ++++++-- config/locales/activerecord.en.yml | 2 +- config/locales/activerecord.es.yml | 2 +- lib/census_api.rb | 6 +++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 353d593b3..936d8af3b 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -11,16 +11,20 @@ class Poll end def has_not_voted - errors.add(:document_number, :has_voted) if has_voted? + errors.add(:document_number, :has_voted, name: name) if has_voted? end def census_api_response - CensusApi.new.call(document_type, document_number) + @census ||= CensusApi.new.call(document_type, document_number) end def has_voted? poll.voters.where(document_number: document_number, document_type: document_type).present? end + def name + @census.name + end + end end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index b719885b5..f34757195 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -87,7 +87,7 @@ en: attributes: document_number: not_in_census: "Document not in census" - has_voted: "Has already voted" + has_voted: "%{name} has already voted" proposal: attributes: tag_list: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 9d51505fe..a439a6c5c 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -87,7 +87,7 @@ es: attributes: document_number: not_in_census: "Este documento no aparece en el censo" - has_voted: "Ya ha votado" + has_voted: "%{name} ya ha votado" proposal: attributes: tag_list: diff --git a/lib/census_api.rb b/lib/census_api.rb index d80f420e7..eadfc549e 100644 --- a/lib/census_api.rb +++ b/lib/census_api.rb @@ -61,6 +61,10 @@ class CensusApi end end + def name + "#{data[:datos_habitante][:item][:nombre]} #{data[:datos_habitante][:item][:apellido1]}" + end + private def data @@ -106,7 +110,7 @@ class CensusApi end def stubbed_valid_response - {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} + {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón", nombre: "José", apellido1: "García" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}} end def stubbed_invalid_response From 5b7783b1802941217ca40a22e434d466a70f1b82 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:54:02 +0200 Subject: [PATCH 079/523] updates db schema --- db/schema.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 0453b852d..75ef4d02c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -270,27 +270,21 @@ ActiveRecord::Schema.define(version: 20161102133838) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree -<<<<<<< HEAD -======= create_table "poll_booths", force: :cascade do |t| t.string "name" t.integer "poll_id" end ->>>>>>> validates voter in census create_table "poll_officers", force: :cascade do |t| t.integer "user_id" end -<<<<<<< HEAD -======= create_table "poll_voters", force: :cascade do |t| t.integer "booth_id" t.string "document_number" t.string "document_type" end ->>>>>>> validates voter in census create_table "polls", force: :cascade do |t| t.string "name" end From f0a7d19f728b831559409b3620a9160fd3b85978 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:55:16 +0200 Subject: [PATCH 080/523] removes officer factory --- spec/factories.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index d29423aa1..d7f9e299c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -267,10 +267,6 @@ FactoryGirl.define do sequence(:name) { |n| "Poll #{n}" } end - factory :poll_officer, class: 'Poll::Officer' do - user - end - factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } poll From 1ac77fad7a317a51e65dec9707904b2420c70066 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 19 Sep 2016 18:56:10 +0200 Subject: [PATCH 081/523] adds spacing to factories --- spec/factories.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/factories.rb b/spec/factories.rb index d7f9e299c..7e09fab89 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -274,6 +274,7 @@ FactoryGirl.define do factory :poll_voter, class: 'Poll::Voter' do association :booth, factory: :budget_booth + trait :valid_document do document_type "1" document_number "12345678Z" From 5b424d1793429c7164861c916b213a1ac9bf5c1a Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 20 Sep 2016 11:44:43 +0200 Subject: [PATCH 082/523] updates query to be more efficient --- app/models/poll/voter.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 936d8af3b..a517c3f34 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -19,7 +19,7 @@ class Poll end def has_voted? - poll.voters.where(document_number: document_number, document_type: document_type).present? + poll.voters.where(document_number: document_number, document_type: document_type).exists? end def name From 5e3fff6825e6b4e362fc24b4ef15776267cb635a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 20 Sep 2016 12:32:23 +0200 Subject: [PATCH 083/523] Adds content to booths index and show views --- app/views/admin/poll/booths/index.html.erb | 9 ++++++--- app/views/admin/poll/booths/show.html.erb | 14 ++++++++++++-- config/locales/admin.en.yml | 4 ++-- config/locales/admin.es.yml | 11 +++++++++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 2e9a2f70b..918479f38 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -22,6 +22,7 @@ <%= t("admin.booths.index.name") %> <%= t("admin.booths.index.location") %> + <%= t("admin.booths.index.officers") %>   @@ -29,15 +30,17 @@ - <%= link_to "Urna Moncloa (REFNUM)", "#" %> + <%= link_to "Urna Moncloa (REFNUM)", "booths/1" %> C/ Isaac Peral, 25. 28003, Madrid + + N <%= t("admin.booths.index.officers") %> + - <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> - <%= link_to t("admin.booths.index.add_officer"), "#", class: "button success" %> + <%= link_to t("admin.actions.edit"), "booths/1/edit", class: "button hollow" %> diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 8a5c2fd99..34e1a4465 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -2,7 +2,7 @@

    Urna Moncloa (REFNUM)

    -<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +<%= link_to t("admin.actions.edit"), "1/edit", class: "button hollow float-right" %>

    <%= t("admin.booths.show.location") %>: C/ Isaac Peral, 25. 28003, Madrid

    @@ -14,7 +14,17 @@
    -<%= link_to t("admin.booths.show.add_officer"), "#", class: "button success" %> +<%= link_to t("admin.booths.show.assign_officer"), "#", class: "button success" %> + +
    + + <%# f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %> + + <%# f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %> + <%# b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %> + <%# end %> +
    <%# @officers.each do |officer| %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 40822778f..40f959a3a 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -188,7 +188,7 @@ en: add_booth: "Add booth" name: "Name" location: "Location" - add_officer: "Add officer" + officers: "Officers" new: title: "Poll %{poll}" subtitle: "New booth" @@ -205,7 +205,7 @@ en: submit_button: "Update booth" show: location: "Location" - add_officer: "Add officer" + assign_officer: "Assign officer" officers_list: "List of officers" no_officers: "There is no officers in this booth." officials: diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 4c807e454..6023da712 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -188,7 +188,7 @@ es: add_booth: "Añadir urna" name: "Nombre" location: "Ubicación" - add_officer: "Añadir presidente" + officers: "Presidentes de mesa" new: title: "Votación %{poll}" subtitle: "Nueva urna" @@ -196,9 +196,16 @@ es: reference: "Número de referencia" location: "Ubicación" submit_button: "Crear urna" + edit: + title: "Votación %{poll}" + subtitle: "Editar urna" + name: "Nombre" + reference: "Número de referencia" + location: "Ubicación" + submit_button: "Actualizar urna" show: location: "Ubicación" - add_officer: "Añadir presidente de mesa" + assign_officer: "Asignar presidente de mesa" officers_list: "Lista de presidentes de mesa" no_officers: "No hay presidentes de mesa en esta urna." officials: From ebb9a5fa1d74b78947289e71ac7492dde38ca7a1 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 20 Sep 2016 13:49:48 +0200 Subject: [PATCH 084/523] fixes specs --- spec/features/management/document_verifications_spec.rb | 4 ++-- spec/features/management/email_verifications_spec.rb | 4 ++-- spec/features/management/managed_users_spec.rb | 4 ++-- spec/features/management/users_spec.rb | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/features/management/document_verifications_spec.rb b/spec/features/management/document_verifications_spec.rb index 674349815..130630762 100644 --- a/spec/features/management/document_verifications_spec.rb +++ b/spec/features/management/document_verifications_spec.rb @@ -47,7 +47,7 @@ feature 'DocumentVerifications' do scenario 'Verifying a user which does exists in the census but not in the db redirects allows sending an email' do visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" @@ -66,7 +66,7 @@ feature 'DocumentVerifications' do expect_any_instance_of(Verification::Management::Document).to receive(:under_sixteen?).and_return(true) visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "You must be over 16 to verify your account." diff --git a/spec/features/management/email_verifications_spec.rb b/spec/features/management/email_verifications_spec.rb index 22987f317..d68d9bd5f 100644 --- a/spec/features/management/email_verifications_spec.rb +++ b/spec/features/management/email_verifications_spec.rb @@ -8,7 +8,7 @@ feature 'EmailVerifications' do user = create(:user) visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" @@ -30,7 +30,7 @@ feature 'EmailVerifications' do expect(page).to_not have_link "Verify my account" expect(page).to have_content "Account verified" - expect(user.reload.document_number).to eq('1234') + expect(user.reload.document_number).to eq('12345678Z') expect(user).to be_level_three_verified end diff --git a/spec/features/management/managed_users_spec.rb b/spec/features/management/managed_users_spec.rb index 78010bc39..6ac04b137 100644 --- a/spec/features/management/managed_users_spec.rb +++ b/spec/features/management/managed_users_spec.rb @@ -57,7 +57,7 @@ feature 'Managed User' do user = create(:user) visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' within(".account-info") do @@ -88,7 +88,7 @@ feature 'Managed User' do login_as_manager visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" diff --git a/spec/features/management/users_spec.rb b/spec/features/management/users_spec.rb index 1a0618e60..694720cc0 100644 --- a/spec/features/management/users_spec.rb +++ b/spec/features/management/users_spec.rb @@ -9,7 +9,7 @@ feature 'Users' do scenario 'Create a level 3 user from scratch' do visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '1234' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "Please introduce the email used on the account" @@ -45,10 +45,10 @@ feature 'Users' do end scenario 'Delete a level 2 user account from document verification page', :js do - level_2_user = create(:user, :level_two, document_number: 13579) + level_2_user = create(:user, :level_two, document_number: "12345678Z") visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '13579' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to_not have_content "This user account is already verified." @@ -62,7 +62,7 @@ feature 'Users' do expect(level_2_user.reload.erase_reason).to eq "Deleted by manager: manager_user_#{Manager.last.user_id}" visit management_document_verifications_path - fill_in 'document_verification_document_number', with: '13579' + fill_in 'document_verification_document_number', with: '12345678Z' click_button 'Check' expect(page).to have_content "no user account associated to it" From 304743f64e712042b0b299c18338bce5a43d237d Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 23 Sep 2016 09:13:02 +0200 Subject: [PATCH 085/523] tmp commit poll index, show and new --- .../admin/poll/polls_controller.rb | 2 +- app/models/abilities/administrator.rb | 2 + app/views/admin/poll/polls/_poll.html.erb | 16 ++++++++ app/views/admin/poll/polls/index.html.erb | 17 +------- app/views/admin/poll/polls/show.html.erb | 6 ++- spec/features/admin/poll/polls_spec.rb | 40 +++++++++++++++++++ 6 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 app/views/admin/poll/polls/_poll.html.erb create mode 100644 spec/features/admin/poll/polls_spec.rb diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index b90fd2c11..eb8b417b8 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -1,5 +1,5 @@ class Admin::Poll::PollsController < Admin::BaseController - skip_authorization_check + load_and_authorize_resource def index end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 0f1100137..bd74e1be9 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -40,6 +40,8 @@ module Abilities can [:search, :create, :index, :destroy], ::Manager can [:search, :create, :index, :destroy], ::Poll::Officer + can [:manage], Poll + can :manage, Annotation can [:read, :update, :destroy, :summary], SpendingProposal diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb new file mode 100644 index 000000000..a9f2dcd1b --- /dev/null +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index c260ab255..b24cc10f6 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -16,21 +16,6 @@ - - - - - - - + <%= render @polls %>
    + + <%= link_to poll.name, admin_poll_path(poll) %> + ß + + Próximamente +
    (15/12/2016 - 15/02/2017) +
    + <%= link_to t("admin.actions.edit"), + edit_admin_poll_path(poll), + class: "button hollow" %> +
     
    - - <%= link_to "Votación de propuestas 2016 (REFNUM)", "polls/3" %> - - - Próximamente -
    (15/12/2016 - 15/02/2017) -
    - <%= link_to t("admin.actions.edit"), "polls/3/edit", class: "button hollow" %> -
    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 9b4971214..105cf2fe6 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -1,8 +1,12 @@ <%= render "shared/back_link" %>
    -

    Votación de propuestas 2016

    +

    + <%= @poll.name %> +

    + <%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +

    (REFNUM)

    Próximamente (15/12/2016 - 15/02/2017)

    <%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb new file mode 100644 index 000000000..a94c81cc9 --- /dev/null +++ b/spec/features/admin/poll/polls_spec.rb @@ -0,0 +1,40 @@ +require 'rails_helper' + +feature 'Admin polls' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'Index' do + 3.times { create(:poll) } + + visit admin_root_path + + within('#side_menu') do + click_link "Polls" + end + + expect(page).to have_css ".poll", count: 3 + + Poll.all.each do |poll| + within("#poll_#{poll.id}") do + expect(page).to have_content poll.name +#expect(page).to have_content "Status/Dates" - Hardcoded + end + end + end + + scenario 'Show', :focus do + poll = create(:poll) + + visit admin_polls_path + click_link poll.name + + expect(page).to have_content poll.name +#expect(page).to have_content "Status/Dates" - Hardcoded +#expect(page).to have_content "REFNUM" - Hardcoded + end + +end \ No newline at end of file From c1a9caeab0a9273df0585bad23dbd785bb9feaae Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:20:38 +0200 Subject: [PATCH 086/523] adds poll CRU actions --- .../admin/poll/polls_controller.rb | 22 ++++++++ app/models/poll.rb | 4 +- app/views/admin/poll/polls/_form.html.erb | 34 ++++++++++++ app/views/admin/poll/polls/_poll.html.erb | 2 +- app/views/admin/poll/polls/edit.html.erb | 5 +- app/views/admin/poll/polls/index.html.erb | 37 ++++++------- app/views/admin/poll/polls/new.html.erb | 33 +----------- app/views/admin/poll/polls/show.html.erb | 6 +-- config/locales/admin.en.yml | 2 +- config/locales/responders.en.yml | 3 +- config/locales/responders.es.yml | 1 + spec/features/admin/poll/polls_spec.rb | 53 ++++++++++++++++++- spec/models/poll_spec.rb | 16 ++++++ 13 files changed, 158 insertions(+), 60 deletions(-) create mode 100644 app/views/admin/poll/polls/_form.html.erb create mode 100644 spec/models/poll_spec.rb diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index eb8b417b8..2a7c1e730 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -10,7 +10,29 @@ class Admin::Poll::PollsController < Admin::BaseController def new end + def create + if @poll.save + redirect_to [:admin, @poll], notice: t("flash.actions.create.poll") + else + render :new + end + end + def edit end + def update + if @poll.update(poll_params) + redirect_to [:admin, @poll], notice: t("flash.actions.update.poll") + else + render :edit + end + end + + private + + def poll_params + params.require(:poll).permit(:name) + end + end \ No newline at end of file diff --git a/app/models/poll.rb b/app/models/poll.rb index 5a429c49d..4543a2544 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,4 +1,6 @@ class Poll < ActiveRecord::Base has_many :booths has_many :voters, through: :booths, class_name: "Poll::Voter" -end + + validates :name, presence: true +end \ No newline at end of file diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb new file mode 100644 index 000000000..64d7177a6 --- /dev/null +++ b/app/views/admin/poll/polls/_form.html.erb @@ -0,0 +1,34 @@ +<%= form_for [:admin, @poll] do |f| %> +
    +
    + <%= f.text_field :name, + placeholder: t('admin.polls.new.name'), + label: t("admin.polls.new.name") %> +
    + +
    + + +
    +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + +
    +
    +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index a9f2dcd1b..4128ad222 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -2,7 +2,7 @@ <%= link_to poll.name, admin_poll_path(poll) %> - ß + Próximamente diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb index 68eb7cc3b..0158655a5 100644 --- a/app/views/admin/poll/polls/edit.html.erb +++ b/app/views/admin/poll/polls/edit.html.erb @@ -1,8 +1,9 @@ <%= render 'shared/back_link' %>

    <%= t("admin.polls.edit.title") %>

    +<%= render "form" %> -
    +
    \ No newline at end of file diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index b24cc10f6..2954e44b8 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -1,21 +1,22 @@

    <%= t("admin.polls.index.title") %>

    -<%= link_to t("admin.polls.index.create"), new_admin_poll_path, class: "button success float-right" %> +<%= link_to t("admin.polls.index.create"), + new_admin_poll_path, + class: "button success float-right" %> - -
    - <%= t("admin.polls.index.no_polls") %> -
    - - - - - - - - - - - <%= render @polls %> - -
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %> 
    +<% if Poll.any? %> + + + + + + + + <%= render @polls %> + +
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %> 
    +<% else %> +
    + <%= t("admin.polls.index.no_polls") %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/new.html.erb b/app/views/admin/poll/polls/new.html.erb index b2d74cffc..ba1ae7260 100644 --- a/app/views/admin/poll/polls/new.html.erb +++ b/app/views/admin/poll/polls/new.html.erb @@ -2,35 +2,4 @@

    <%= t("admin.polls.new.title") %>

    -
    -
    -
    - - -
    - -
    - - -
    -
    - -
    -
    - - -
    - -
    - - -
    -
    - -
    -
    - -
    -
    - -
    \ No newline at end of file +<%= render "form" %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 105cf2fe6..1b0d1e198 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -5,7 +5,7 @@ <%= @poll.name %> -<%= link_to t("admin.actions.edit"), "#", class: "button hollow float-right" %> +<%= link_to t("admin.actions.edit"), edit_admin_poll_path(@poll), class: "button hollow float-right" %>

    (REFNUM)

    Próximamente (15/12/2016 - 15/02/2017)

    @@ -26,7 +26,7 @@   - + <%= @poll.booths.each do |booth| %> @@ -40,6 +40,6 @@ <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> - + <% end %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 40f959a3a..bb8093b03 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -155,7 +155,7 @@ en: polls: index: title: "List of polls" - no_polls: "There are any poll." + no_polls: "There are no polls." create: "Create poll" name: "Name" status: "Status" diff --git a/config/locales/responders.en.yml b/config/locales/responders.en.yml index ab1641799..422a59e0c 100755 --- a/config/locales/responders.en.yml +++ b/config/locales/responders.en.yml @@ -6,15 +6,16 @@ en: notice: "%{resource_name} created successfully." debate: "Debate created successfully." direct_message: "You message has been sent successfully." + poll: "Poll created successfully." proposal: "Proposal created successfully." proposal_notification: "Your message has been sent correctly." spending_proposal: "Spending proposal created successfully. You can access it from %{activity}" - save_changes: notice: Changes saved update: notice: "%{resource_name} updated successfully." debate: "Debate updated successfully." + poll: "Poll updated successfully." proposal: "Proposal updated successfully." spending_proposal: "Investment project updated succesfully." destroy: diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index 387085d69..c9292b187 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -6,6 +6,7 @@ es: notice: "%{resource_name} creado correctamente." debate: "Debate creado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente." + poll: "Votación presencial creada correctamente." proposal: "Propuesta creada correctamente." proposal_notification: "Tu message ha sido enviado correctamente." spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}" diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index a94c81cc9..8d130e67a 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -7,6 +7,15 @@ feature 'Admin polls' do login_as(admin.user) end + scenario 'Index empty' do + visit admin_root_path + within('#side_menu') do + click_link "Polls" + end + + expect(page).to have_content "There are no polls" + end + scenario 'Index' do 3.times { create(:poll) } @@ -24,9 +33,10 @@ feature 'Admin polls' do #expect(page).to have_content "Status/Dates" - Hardcoded end end + expect(page).to_not have_content "There are no polls" end - scenario 'Show', :focus do + scenario 'Show' do poll = create(:poll) visit admin_polls_path @@ -37,4 +47,45 @@ feature 'Admin polls' do #expect(page).to have_content "REFNUM" - Hardcoded end + scenario "Create" do + visit admin_polls_path + click_link "Create poll" + + fill_in "poll_name", with: "Upcoming poll" +#fill_in reference_number - Hardcoded +#fill_in open_date - Hardcoded +#fill_in close_date - Hardcoded + click_button "Create poll" + expect(page).to have_content "Poll created successfully" + + expect(page).to have_content "Upcoming poll" + end + + scenario "Edit" do + poll = create(:poll) + + visit admin_poll_path(poll) + click_link "Edit" +save_and_open_page + fill_in "poll_name", with: "Next Poll" +#fill_in reference_number - Hardcoded +#fill_in open_date - Hardcoded +#fill_in close_date - Hardcoded + click_button "Update poll" + expect(page).to have_content "Poll updated successfully" + + expect(page).to have_content "Next Poll" + end + + scenario 'Edit from index' do + poll = create(:poll) + visit admin_polls_path + + within("#poll_#{poll.id}") do + click_link "Edit" + end + + expect(current_path).to eq(edit_admin_poll_path(poll)) + end + end \ No newline at end of file diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb new file mode 100644 index 000000000..7442cdc5a --- /dev/null +++ b/spec/models/poll_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +describe :poll do + + let(:poll) { build(:poll) } + + it "should be valid" do + expect(poll).to be_valid + end + + it "should not be valid without a name" do + poll.name = nil + expect(poll).to_not be_valid + end + +end \ No newline at end of file From fda2f3c89ef76582a8ab6d06d8c7a13309a265cf Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:21:34 +0200 Subject: [PATCH 087/523] adds admin submit button helper --- app/helpers/admin_helper.rb | 4 ++++ spec/helpers/admin_helper_spec.rb | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 spec/helpers/admin_helper_spec.rb diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 39ab74b96..f14269fb3 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -16,6 +16,10 @@ module AdminHelper Administrator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] } end + def admin_submit_action(resource) + resource.persisted? ? "edit" : "new" + end + private def namespace diff --git a/spec/helpers/admin_helper_spec.rb b/spec/helpers/admin_helper_spec.rb new file mode 100644 index 000000000..0239f1926 --- /dev/null +++ b/spec/helpers/admin_helper_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +describe AdminHelper do + + describe "#admin_submit_action" do + + it "returns new when the the resource has not been persisted" do + poll = build(:poll) + expect(admin_submit_action(poll)).to eq("new") + end + + it "returns edit when the the resource has been persisted" do + poll = create(:poll) + expect(admin_submit_action(poll)).to eq("edit") + end + + end + +end \ No newline at end of file From 3251e4944e7a93b3b042f3a81a87b4eedcaf1487 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:21:58 +0200 Subject: [PATCH 088/523] allow officers to be created without a poll --- app/controllers/admin/poll/officers_controller.rb | 4 ++-- app/views/admin/_menu.html.erb | 14 ++++++++------ app/views/admin/poll/officers/index.html.erb | 4 ++-- config/routes.rb | 6 +++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/app/controllers/admin/poll/officers_controller.rb b/app/controllers/admin/poll/officers_controller.rb index 7f6f918d7..2641a12b5 100644 --- a/app/controllers/admin/poll/officers_controller.rb +++ b/app/controllers/admin/poll/officers_controller.rb @@ -22,12 +22,12 @@ class Admin::Poll::OfficersController < Admin::BaseController @officer.user_id = params[:user_id] @officer.save - redirect_to admin_poll_officers_path + redirect_to admin_officers_path end def destroy @officer.destroy - redirect_to admin_poll_officers_path + redirect_to admin_officers_path end def show diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 48736c378..0661a3bb6 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -84,7 +84,7 @@
  • > - <%= link_to admin_poll_officers_path(Poll.last) do %> + <%= link_to admin_officers_path do %> <%= t('admin.menu.poll_officers') %> <% end %>
  • @@ -95,11 +95,13 @@ <% end %> -
  • > - <%= link_to admin_poll_booths_url(Poll.last) do %> - <%= t('admin.menu.booths') %> - <% end %> -
  • + <% if Poll.any? %> +
  • > + <%= link_to admin_poll_booths_url(Poll.last) do %> + <%= t('admin.menu.booths') %> + <% end %> +
  • + <% end %>
  • > <%= link_to admin_activity_path do %> diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index 56daabb94..cc6393204 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -1,7 +1,7 @@

    <%= t("admin.poll_officers.index.title") %>

    - <%= form_tag search_admin_poll_officers_path, method: :get, remote: true do %> + <%= form_tag search_admin_officers_path, method: :get, remote: true do %>
    <%= text_field_tag :email, '', placeholder: t('admin.poll_officers.search.email_placeholder') %>
    @@ -27,7 +27,7 @@ <% if officer.persisted? %> <%= link_to t('admin.poll_officers.officer.delete'), - admin_poll_officer_path(Poll.last, officer), + admin_officer_path(officer), method: :delete, class: "button hollow alert" %> diff --git a/config/routes.rb b/config/routes.rb index 2b223b46b..9de943f7d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -180,11 +180,11 @@ Rails.application.routes.draw do end scope module: 'poll' do + resources :officers do + get :search, on: :collection + end resources :polls do resources :booths - resources :officers do - get :search, on: :collection - end end end From daac86a7a835163f2a2ea476f3304f98ca816dda Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 25 Sep 2016 10:26:32 +0200 Subject: [PATCH 089/523] removes poll unused attributes --- app/views/admin/poll/polls/_form.html.erb | 22 ++------------- app/views/admin/poll/polls/edit.html.erb | 34 +---------------------- spec/features/admin/poll/polls_spec.rb | 19 ++++--------- 3 files changed, 8 insertions(+), 67 deletions(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 64d7177a6..77961912c 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -5,30 +5,12 @@ placeholder: t('admin.polls.new.name'), label: t("admin.polls.new.name") %>
    - -
    - - -
    - - -
    -
    - - -
    - -
    - - -
    - + <%= f.submit t("admin.polls.#{admin_submit_action(@poll)}.submit_button"), + class: "button success expanded" %>
    <% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/edit.html.erb b/app/views/admin/poll/polls/edit.html.erb index 0158655a5..cf131203f 100644 --- a/app/views/admin/poll/polls/edit.html.erb +++ b/app/views/admin/poll/polls/edit.html.erb @@ -1,37 +1,5 @@ <%= render 'shared/back_link' %>

    <%= t("admin.polls.edit.title") %>

    -<%= render "form" %> - - - \ No newline at end of file +<%= render "form" %> \ No newline at end of file diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 8d130e67a..bab7b5847 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -30,7 +30,6 @@ feature 'Admin polls' do Poll.all.each do |poll| within("#poll_#{poll.id}") do expect(page).to have_content poll.name -#expect(page).to have_content "Status/Dates" - Hardcoded end end expect(page).to_not have_content "There are no polls" @@ -43,8 +42,6 @@ feature 'Admin polls' do click_link poll.name expect(page).to have_content poll.name -#expect(page).to have_content "Status/Dates" - Hardcoded -#expect(page).to have_content "REFNUM" - Hardcoded end scenario "Create" do @@ -52,12 +49,9 @@ feature 'Admin polls' do click_link "Create poll" fill_in "poll_name", with: "Upcoming poll" -#fill_in reference_number - Hardcoded -#fill_in open_date - Hardcoded -#fill_in close_date - Hardcoded click_button "Create poll" - expect(page).to have_content "Poll created successfully" + expect(page).to have_content "Poll created successfully" expect(page).to have_content "Upcoming poll" end @@ -66,14 +60,11 @@ feature 'Admin polls' do visit admin_poll_path(poll) click_link "Edit" -save_and_open_page - fill_in "poll_name", with: "Next Poll" -#fill_in reference_number - Hardcoded -#fill_in open_date - Hardcoded -#fill_in close_date - Hardcoded - click_button "Update poll" - expect(page).to have_content "Poll updated successfully" + fill_in "poll_name", with: "Next Poll" + click_button "Update poll" + + expect(page).to have_content "Poll updated successfully" expect(page).to have_content "Next Poll" end From 6e6d2ac753fa1efd2009b45e02cb400f2817b013 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:53:46 +0200 Subject: [PATCH 090/523] moves poll spec to poll folder --- spec/models/{ => poll}/poll_spec.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/models/{ => poll}/poll_spec.rb (100%) diff --git a/spec/models/poll_spec.rb b/spec/models/poll/poll_spec.rb similarity index 100% rename from spec/models/poll_spec.rb rename to spec/models/poll/poll_spec.rb From c4bc484afb287741b3bbaf6dc499df12592f4f9c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:54:29 +0200 Subject: [PATCH 091/523] updates dev seeds with booths --- db/dev_seeds.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index d3d9749b3..51f46b3c6 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -363,4 +363,8 @@ puts "Creating polls" 3.times.each_with_index do |i| Poll.create(name: "Poll #{i}") +end + +10.times.each_with_index do |i| + Poll::Booth.create(name: "Booth #{i}", poll: Poll.all.sample) end \ No newline at end of file From 6d7d6e67eae55d9433ceec527b0262d535c6f819 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:55:11 +0200 Subject: [PATCH 092/523] adds consistency to syntax --- app/views/admin/poll/polls/index.html.erb | 2 +- config/routes.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index 2954e44b8..b4c18d21b 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -4,7 +4,7 @@ new_admin_poll_path, class: "button success float-right" %> -<% if Poll.any? %> +<% if @polls.any? %> diff --git a/config/routes.rb b/config/routes.rb index 9de943f7d..16625aa7c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -179,7 +179,7 @@ Rails.application.routes.draw do get :search, on: :collection end - scope module: 'poll' do + scope module: :poll do resources :officers do get :search, on: :collection end From 63ccac963a3b21be201a4a5608a46dd9bb826c52 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:56:19 +0200 Subject: [PATCH 093/523] adds booth backend for index, show, create and edit actions --- .../admin/poll/booths_controller.rb | 31 +++- app/models/abilities/administrator.rb | 5 +- app/models/poll/booth.rb | 2 + app/views/admin/poll/booths/_form.html.erb | 20 +++ app/views/admin/poll/booths/edit.html.erb | 29 +--- app/views/admin/poll/booths/index.html.erb | 49 +++--- app/views/admin/poll/booths/new.html.erb | 29 +--- app/views/admin/poll/booths/show.html.erb | 13 +- app/views/admin/poll/polls/show.html.erb | 4 +- config/locales/admin.en.yml | 4 +- config/locales/responders.en.yml | 2 + config/locales/responders.es.yml | 3 + .../20160926090107_add_location_to_booths.rb | 5 + db/schema.rb | 5 + spec/factories.rb | 1 + spec/features/admin/poll/booths_spec.rb | 146 ++++++++++++++++++ spec/models/abilities/administrator_spec.rb | 3 + spec/models/poll/booth_spec.rb | 16 ++ 18 files changed, 287 insertions(+), 80 deletions(-) create mode 100644 app/views/admin/poll/booths/_form.html.erb create mode 100644 db/migrate/20160926090107_add_location_to_booths.rb create mode 100644 spec/features/admin/poll/booths_spec.rb create mode 100644 spec/models/poll/booth_spec.rb diff --git a/app/controllers/admin/poll/booths_controller.rb b/app/controllers/admin/poll/booths_controller.rb index 9b1e62f8f..95057ce2f 100644 --- a/app/controllers/admin/poll/booths_controller.rb +++ b/app/controllers/admin/poll/booths_controller.rb @@ -1,5 +1,8 @@ class Admin::Poll::BoothsController < Admin::BaseController - skip_authorization_check + load_and_authorize_resource :poll + load_and_authorize_resource class: 'Poll::Booth', through: :poll + + before_action :load_polls, only: :index def index end @@ -10,7 +13,33 @@ class Admin::Poll::BoothsController < Admin::BaseController def new end + def create + if @booth.save + redirect_to admin_poll_booth_path(@poll, @booth), notice: t("flash.actions.create.poll_booth") + else + render :new + end + end + def edit end + def update + if @booth.update(booth_params) + redirect_to admin_poll_booth_path(@poll, @booth), notice: t("flash.actions.update.poll_booth") + else + render :edit + end + end + + private + + def booth_params + params.require(:poll_booth).permit(:name, :location) + end + + def load_polls + @polls = Poll.all + end + end \ No newline at end of file diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index bd74e1be9..a0e040ab3 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -40,12 +40,13 @@ module Abilities can [:search, :create, :index, :destroy], ::Manager can [:search, :create, :index, :destroy], ::Poll::Officer - can [:manage], Poll - can :manage, Annotation can [:read, :update, :destroy, :summary], SpendingProposal can [:search, :edit, :update, :create, :index, :destroy], Banner + + can [:manage], Poll + can [:manage], Poll::Booth end end end diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index a05f3d547..eb7d81b8c 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -2,5 +2,7 @@ class Poll class Booth < ActiveRecord::Base belongs_to :poll has_many :voters + + validates :name, presence: true end end \ No newline at end of file diff --git a/app/views/admin/poll/booths/_form.html.erb b/app/views/admin/poll/booths/_form.html.erb new file mode 100644 index 000000000..31d60c0f0 --- /dev/null +++ b/app/views/admin/poll/booths/_form.html.erb @@ -0,0 +1,20 @@ +
    +
    + <%= f.text_field :name, + placeholder: t('admin.booths.new.name'), + label: t("admin.booths.new.name") %> +
    + +
    + <%= f.text_field :location, + placeholder: t("admin.booths.new.location"), + label: t("admin.booths.new.location") %> +
    +
    + +
    +
    + <%= f.submit t("admin.booths.#{admin_submit_action(@booth)}.submit_button"), + class: "button success expanded" %> +
    +
    \ No newline at end of file diff --git a/app/views/admin/poll/booths/edit.html.erb b/app/views/admin/poll/booths/edit.html.erb index e48db9cdd..23d825b91 100644 --- a/app/views/admin/poll/booths/edit.html.erb +++ b/app/views/admin/poll/booths/edit.html.erb @@ -1,28 +1,7 @@ <%= render 'shared/back_link' %> -

    <%= t("admin.booths.edit.title") %>: <%= t("admin.booths.edit.subtitle") %>

    +

    <%= t("admin.booths.edit.title", poll: @poll.name) %>: <%= t("admin.booths.edit.subtitle") %>

    -
    -
    -
    - - -
    - -
    - - -
    - -
    - - "> -
    -
    - -
    -
    - -
    -
    - +<%= form_for @booth, url: admin_poll_booth_path(@poll, @booth) do |f| %> + <%= render "form", f: f %> +<% end %> diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index 918479f38..b3733670d 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -1,22 +1,27 @@

    <%= t("admin.booths.index.title") %>

    -
    -
    - -
    - - -

    <%= t("admin.booths.index.title_list") %>

    - - -
    - <%= t("admin.booths.index.no_booths") %> +
    + <%= form_tag '', method: :get do %> + <%= select_tag "poll_id", + options_for_select(@polls.collect {|poll| + [poll.name, admin_poll_booths_path(poll)] + }), + prompt: t("admin.booths.index.select_poll"), + class: "js-location-changer" %> + <% end %>
    - -<%= link_to t("admin.booths.index.add_booth"), new_admin_poll_booth_path, class: "button success" %> +

    <%= t("admin.booths.index.title_list", poll: @poll.name) %>

    + +<% if @booths.empty? %> +
    + <%= t("admin.booths.index.no_booths") %> +
    +<% end %> + +<%= link_to t("admin.booths.index.add_booth"), + new_admin_poll_booth_path, + class: "button success" %>
    <%= t("admin.polls.index.name") %>
    @@ -26,23 +31,25 @@ - - + <% @booths.each do |booth| %> + - + <% end %>
     
    - <%= link_to "Urna Moncloa (REFNUM)", "booths/1" %> + <%= link_to booth.name, admin_poll_booth_path(@poll, booth) %> - C/ Isaac Peral, 25. 28003, Madrid + <%= booth.location %> N <%= t("admin.booths.index.officers") %> - <%= link_to t("admin.actions.edit"), "booths/1/edit", class: "button hollow" %> + <%= link_to t("admin.actions.edit"), + edit_admin_poll_booth_path(@poll, booth), + class: "button hollow" %>
    diff --git a/app/views/admin/poll/booths/new.html.erb b/app/views/admin/poll/booths/new.html.erb index e83d2f47c..cffcfab72 100644 --- a/app/views/admin/poll/booths/new.html.erb +++ b/app/views/admin/poll/booths/new.html.erb @@ -1,28 +1,7 @@ <%= render 'shared/back_link' %> -

    <%= t("admin.booths.new.title") %>: <%= t("admin.booths.new.subtitle") %>

    +

    <%= t("admin.booths.new.title", poll: @poll.name) %>: <%= t("admin.booths.new.subtitle") %>

    -
    -
    -
    - - -
    - -
    - - -
    - -
    - - "> -
    -
    - -
    -
    - -
    -
    -
    +<%= form_for @booth, url: admin_poll_booths_path(@poll) do |f| %> + <%= render "form", f: f %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 34e1a4465..55f7d5504 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -1,10 +1,17 @@ <%= render 'shared/back_link' %>
    -

    Urna Moncloa (REFNUM)

    -<%= link_to t("admin.actions.edit"), "1/edit", class: "button hollow float-right" %> +

    + <%= @booth.name %> +

    +<%= link_to t("admin.actions.edit"), + edit_admin_poll_booth_path(@poll, @booth), + class: "button hollow float-right" %> -

    <%= t("admin.booths.show.location") %>: C/ Isaac Peral, 25. 28003, Madrid

    +

    + <%= t("admin.booths.show.location") %>: + <%= @booth.location %> +

    <%= t("admin.booths.show.officers_list") %>

    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 1b0d1e198..17248d4b9 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -5,7 +5,9 @@ <%= @poll.name %> -<%= link_to t("admin.actions.edit"), edit_admin_poll_path(@poll), class: "button hollow float-right" %> +<%= link_to t("admin.actions.edit"), + edit_admin_poll_path(@poll), + class: "button hollow float-right" %>

    (REFNUM)

    Próximamente (15/12/2016 - 15/02/2017)

    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index bb8093b03..db4cf34ca 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -174,7 +174,7 @@ en: close_date: "Close date" submit_button: "Update poll" show: - no_booths: "There is no booths in this poll." + no_booths: "There are no booths in this poll." add_booth: "Add booth" booths_title: "List of booths" name: "Name" @@ -184,7 +184,7 @@ en: title: "List of booths" select_poll: "Select a poll" title_list: "List of booths of poll %{poll}" - no_booths: "There is no booths in this poll." + no_booths: "There are no booths in this poll." add_booth: "Add booth" name: "Name" location: "Location" diff --git a/config/locales/responders.en.yml b/config/locales/responders.en.yml index 422a59e0c..68d77b0d2 100755 --- a/config/locales/responders.en.yml +++ b/config/locales/responders.en.yml @@ -7,6 +7,7 @@ en: debate: "Debate created successfully." direct_message: "You message has been sent successfully." poll: "Poll created successfully." + poll_booth: "Booth created successfully." proposal: "Proposal created successfully." proposal_notification: "Your message has been sent correctly." spending_proposal: "Spending proposal created successfully. You can access it from %{activity}" @@ -16,6 +17,7 @@ en: notice: "%{resource_name} updated successfully." debate: "Debate updated successfully." poll: "Poll updated successfully." + poll_booth: "Booth updated successfully." proposal: "Proposal updated successfully." spending_proposal: "Investment project updated succesfully." destroy: diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index c9292b187..105b00903 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -7,6 +7,7 @@ es: debate: "Debate creado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente." poll: "Votación presencial creada correctamente." + poll_booth: "Urna creada correctamente." proposal: "Propuesta creada correctamente." proposal_notification: "Tu message ha sido enviado correctamente." spending_proposal: "Propuesta de inversión creada correctamente. Puedes acceder a ella desde %{activity}" @@ -16,6 +17,8 @@ es: notice: "%{resource_name} actualizado correctamente." debate: "Debate actualizado correctamente." proposal: "Propuesta actualizada correctamente." + poll: "Votación presencial actualizada correctamente." + poll_booth: "Urna actualizada correctamente." spending_proposal: "Propuesta de inversión actualizada correctamente." destroy: spending_proposal: "Propuesta de inversión eliminada." \ No newline at end of file diff --git a/db/migrate/20160926090107_add_location_to_booths.rb b/db/migrate/20160926090107_add_location_to_booths.rb new file mode 100644 index 000000000..146f55d41 --- /dev/null +++ b/db/migrate/20160926090107_add_location_to_booths.rb @@ -0,0 +1,5 @@ +class AddLocationToBooths < ActiveRecord::Migration + def change + add_column :poll_booths, :location, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 75ef4d02c..2da00cfe2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -273,6 +273,11 @@ ActiveRecord::Schema.define(version: 20161102133838) do create_table "poll_booths", force: :cascade do |t| t.string "name" t.integer "poll_id" + t.string "location" + end + + create_table "poll_officers", force: :cascade do |t| + t.integer "user_id" end create_table "poll_officers", force: :cascade do |t| diff --git a/spec/factories.rb b/spec/factories.rb index 7e09fab89..2ef46540e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -269,6 +269,7 @@ FactoryGirl.define do factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } + sequence(:location) { |n| "Street #{n}" } poll end diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb new file mode 100644 index 000000000..ad46c67fb --- /dev/null +++ b/spec/features/admin/poll/booths_spec.rb @@ -0,0 +1,146 @@ +require 'rails_helper' + +feature 'Admin booths' do + + let!(:poll) { create(:poll) } + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'Index empty' do + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + expect(page).to have_content "There are no booths in this poll" + end + + scenario 'No link to booths when no polls' do + Poll.destroy_all + + visit admin_root_path + + within('#side_menu') do + expect(page).to_not have_link "Booths" + end + end + + scenario 'Index' do + 3.times { create(:poll_booth, poll: poll) } + + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + expect(page).to have_css ".booth", count: 3 + + booths = Poll::Booth.all + booths.each do |booth| + within("#booth_#{booth.id}") do + expect(page).to have_content booth.name + expect(page).to have_content booth.location + end + end + expect(page).to_not have_content "There are no booths" + end + + scenario "Index default to last poll" do + poll1 = create(:poll) + poll2 = create(:poll) + + booth1 = create(:poll_booth, poll: poll1) + booth2 = create(:poll_booth, poll: poll2) + + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + expect(page).to have_css ".booth", count: 1 + expect(page).to have_content booth2.name + expect(page).to_not have_content booth1.name + end + + scenario "Index select poll", :js do + poll1 = create(:poll) + poll2 = create(:poll) + + booth1 = create(:poll_booth, poll: poll1) + booth2 = create(:poll_booth, poll: poll2) + + visit admin_root_path + + within('#side_menu') do + click_link "Booths" + end + + select poll1.name, from: "poll_id" + + expect(page).to have_content "List of booths of poll #{poll1.name}" + expect(page).to have_css ".booth", count: 1 + expect(page).to have_content booth1.name + expect(page).to_not have_content booth2.name + end + + scenario 'Show' do + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booths_path(poll) + click_link booth.name + + expect(page).to have_content booth.name + expect(page).to have_content booth.location + end + + scenario "Create" do + visit admin_poll_booths_path(poll) + click_link "Add booth" + + expect(page).to have_content "Poll #{poll.name}" + + fill_in "poll_booth_name", with: "Upcoming booth" + fill_in "poll_booth_location", with: "39th Street, number 2, ground floor" + click_button "Create booth" + + expect(page).to have_content "Booth created successfully" + expect(page).to have_content "Upcoming booth" + expect(page).to have_content "39th Street, number 2, ground floor" + end + + scenario "Edit" do + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booths_path(poll) + + click_link "Edit" + + expect(page).to have_content "Poll #{poll.name}" + + fill_in "poll_booth_name", with: "Next booth" + fill_in "poll_booth_location", with: "40th Street, number 1, firts floor" + click_button "Update booth" + + expect(page).to have_content "Booth updated successfully" + expect(page).to have_content "Next booth" + expect(page).to have_content "40th Street, number 1, firts floor" + end + + scenario 'Edit from index' do + booth = create(:poll_booth, poll: poll) + visit admin_poll_booths_path(poll) + + within("#booth_#{booth.id}") do + click_link "Edit" + end + + expect(current_path).to eq(edit_admin_poll_booth_path(poll, booth)) + end + +end \ No newline at end of file diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb index f9ed7a0c5..04fd199f0 100644 --- a/spec/models/abilities/administrator_spec.rb +++ b/spec/models/abilities/administrator_spec.rb @@ -56,4 +56,7 @@ describe "Abilities::Administrator" do it { should be_able_to(:update, SpendingProposal) } it { should be_able_to(:valuate, SpendingProposal) } it { should be_able_to(:destroy, SpendingProposal) } + + it { should be_able_to(:manage, Poll) } + it { should be_able_to(:manage, Poll::Booth) } end diff --git a/spec/models/poll/booth_spec.rb b/spec/models/poll/booth_spec.rb new file mode 100644 index 000000000..2fabb9c12 --- /dev/null +++ b/spec/models/poll/booth_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +describe :booth do + + let(:booth) { build(:poll_booth) } + + it "should be valid" do + expect(booth).to be_valid + end + + it "should not be valid without a name" do + booth.name = nil + expect(booth).to_not be_valid + end + +end \ No newline at end of file From 963bb4b60210924a38f8be43279a34ee4d355fc9 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:56:48 +0200 Subject: [PATCH 094/523] removes unused attributes from poll show --- app/views/admin/poll/polls/_poll.html.erb | 4 ---- app/views/admin/poll/polls/show.html.erb | 2 -- 2 files changed, 6 deletions(-) diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index 4128ad222..d90fed14a 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -4,10 +4,6 @@ <%= link_to poll.name, admin_poll_path(poll) %>
    - - Próximamente -
    (15/12/2016 - 15/02/2017) - <%= link_to t("admin.actions.edit"), edit_admin_poll_path(poll), diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 17248d4b9..8a02ebfd7 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -9,8 +9,6 @@ edit_admin_poll_path(@poll), class: "button hollow float-right" %> -

    (REFNUM)

    -

    Próximamente (15/12/2016 - 15/02/2017)

    <%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> From e810fe3e341040d80e3cef46dee9019b636c031f Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 12:01:58 +0200 Subject: [PATCH 095/523] maintains poll date and status in index for demo --- app/views/admin/poll/polls/_poll.html.erb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index d90fed14a..4128ad222 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -4,6 +4,10 @@ <%= link_to poll.name, admin_poll_path(poll) %> + + Próximamente +
    (15/12/2016 - 15/02/2017) + <%= link_to t("admin.actions.edit"), edit_admin_poll_path(poll), From de330b1c0262760a0d9e3e736dd7d372d7ba9504 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 12:34:24 +0200 Subject: [PATCH 096/523] adds booth info to poll show --- app/views/admin/poll/booths/_booth.html.erb | 18 +++++++ app/views/admin/poll/booths/index.html.erb | 21 +------- app/views/admin/poll/polls/show.html.erb | 55 +++++++++------------ config/locales/admin.en.yml | 1 + config/locales/admin.es.yml | 1 + spec/features/admin/poll/polls_spec.rb | 44 ++++++++++++++++- 6 files changed, 88 insertions(+), 52 deletions(-) create mode 100644 app/views/admin/poll/booths/_booth.html.erb diff --git a/app/views/admin/poll/booths/_booth.html.erb b/app/views/admin/poll/booths/_booth.html.erb new file mode 100644 index 000000000..ff1683867 --- /dev/null +++ b/app/views/admin/poll/booths/_booth.html.erb @@ -0,0 +1,18 @@ + + + + <%= link_to booth.name, admin_poll_booth_path(@poll, booth) %> + + + + <%= booth.location %> + + + N <%= t("admin.booths.index.officers") %> + + + <%= link_to t("admin.actions.edit"), + edit_admin_poll_booth_path(@poll, booth), + class: "button hollow" %> + + \ No newline at end of file diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index b3733670d..d2a9a7e5a 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -20,7 +20,7 @@ <% end %> <%= link_to t("admin.booths.index.add_booth"), - new_admin_poll_booth_path, + new_admin_poll_booth_path(@poll), class: "button success" %> @@ -32,24 +32,7 @@ <% @booths.each do |booth| %> - - - - - - + <%= render partial: "booth", locals: { booth: booth } %> <% end %>
    - - <%= link_to booth.name, admin_poll_booth_path(@poll, booth) %> - - - <%= booth.location %> - - N <%= t("admin.booths.index.officers") %> - - <%= link_to t("admin.actions.edit"), - edit_admin_poll_booth_path(@poll, booth), - class: "button hollow" %> -
    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 8a02ebfd7..bed01af41 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -9,37 +9,28 @@ edit_admin_poll_path(@poll), class: "button hollow float-right" %> -<%= link_to t("admin.polls.show.add_booth"), "#", class: "button success" %> +<%= link_to t("admin.polls.show.add_booth"), + new_admin_poll_booth_path(@poll), + class: "button success" %> - -
    - <%= t("admin.polls.show.no_booths") %> -
    - +<% if @poll.booths.empty? %> +
    + <%= t("admin.polls.show.no_booths") %> +
    +<% else %> +

    <%= t("admin.polls.show.booths_title") %>

    -

    <%= t("admin.polls.show.booths_title") %>

    - - - - - - - - - <%= @poll.booths.each do |booth| %> - - - - - - <% end %> - -
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> 
    - - <%= link_to "Urna Moncloa (REFNUM)", "#" %> - - - C/ Isaac Peral, 25. 28003, Madrid - - <%= link_to t("admin.actions.edit"), "#", class: "button hollow" %> -
    + + + + + + + + + <% @poll.booths.each do |booth| %> + <%= render partial: "admin/poll/booths/booth", locals: { booth: booth } %> + <% end %> + +
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %><%= t("admin.polls.show.officers") %> 
    +<% end %> \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index db4cf34ca..ef294262d 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -179,6 +179,7 @@ en: booths_title: "List of booths" name: "Name" location: "Location" + officers: "Officers" booths: index: title: "List of booths" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 6023da712..48dfe2959 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -179,6 +179,7 @@ es: booths_title: "Listado de urnas" name: "Nombre" location: "Ubicación" + officers: "Presidentes de mesa" booths: index: title: "Lista de urnas" diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index bab7b5847..80f875567 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -27,7 +27,8 @@ feature 'Admin polls' do expect(page).to have_css ".poll", count: 3 - Poll.all.each do |poll| + polls = Poll.all + polls.each do |poll| within("#poll_#{poll.id}") do expect(page).to have_content poll.name end @@ -79,4 +80,45 @@ feature 'Admin polls' do expect(current_path).to eq(edit_admin_poll_path(poll)) end + context "Booths" do + + context "Poll show" do + + scenario "No booths" do + poll = create(:poll) + visit admin_poll_path(poll) + + expect(page).to have_content "There are no booths in this poll." + end + + scenario "Booth list" do + poll = create(:poll) + 3.times { create(:poll_booth, poll: poll) } + + visit admin_poll_path(poll) + + expect(page).to have_css ".booth", count: 3 + + booths = Poll::Booth.all + booths.each do |booth| + within("#booth_#{booth.id}") do + expect(page).to have_content booth.name + expect(page).to have_content booth.location + end + end + expect(page).to_not have_content "There are no booths" + end + + scenario "Add booth" do + poll = create(:poll) + visit admin_poll_path(poll) + + click_link "Add booth" + + expect(current_path).to eq(new_admin_poll_booth_path(poll)) + expect(page).to have_content poll.name + end + end + end + end \ No newline at end of file From 5ba72f0fe3bd7aee202c9827ee74cff34f5ab4c4 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 18:39:01 +0200 Subject: [PATCH 097/523] assigns officers to booths --- .../admin/poll/booths_controller.rb | 3 +- app/helpers/officers_helper.rb | 7 + app/models/poll/booth.rb | 2 + app/models/poll/officing_booth.rb | 6 + app/views/admin/poll/booths/show.html.erb | 40 +++--- config/locales/admin.en.yml | 2 +- .../20160928113143_create_officing_booths.rb | 9 ++ db/schema.rb | 7 +- spec/factories.rb | 12 ++ spec/features/admin/poll/officers_spec.rb | 129 +++++++++++++++++- 10 files changed, 189 insertions(+), 28 deletions(-) create mode 100644 app/helpers/officers_helper.rb create mode 100644 app/models/poll/officing_booth.rb create mode 100644 db/migrate/20160928113143_create_officing_booths.rb diff --git a/app/controllers/admin/poll/booths_controller.rb b/app/controllers/admin/poll/booths_controller.rb index 95057ce2f..1d05ddab5 100644 --- a/app/controllers/admin/poll/booths_controller.rb +++ b/app/controllers/admin/poll/booths_controller.rb @@ -8,6 +8,7 @@ class Admin::Poll::BoothsController < Admin::BaseController end def show + @officers = Poll::Officer.all end def new @@ -35,7 +36,7 @@ class Admin::Poll::BoothsController < Admin::BaseController private def booth_params - params.require(:poll_booth).permit(:name, :location) + params.require(:poll_booth).permit(:name, :location, officer_ids: []) end def load_polls diff --git a/app/helpers/officers_helper.rb b/app/helpers/officers_helper.rb new file mode 100644 index 000000000..f29bcf728 --- /dev/null +++ b/app/helpers/officers_helper.rb @@ -0,0 +1,7 @@ +module OfficersHelper + + def officer_label(officer) + truncate([officer.name, officer.email].compact.join(' - '), length: 100) + end + +end \ No newline at end of file diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index eb7d81b8c..74c4c3edb 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -2,6 +2,8 @@ class Poll class Booth < ActiveRecord::Base belongs_to :poll has_many :voters + has_many :officing_booths, dependent: :destroy + has_many :officers, through: :officing_booths validates :name, presence: true end diff --git a/app/models/poll/officing_booth.rb b/app/models/poll/officing_booth.rb new file mode 100644 index 000000000..f0a64721a --- /dev/null +++ b/app/models/poll/officing_booth.rb @@ -0,0 +1,6 @@ +class Poll + class OfficingBooth < ActiveRecord::Base + belongs_to :officer + belongs_to :booth + end +end diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 55f7d5504..cce704d2c 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -15,34 +15,32 @@

    <%= t("admin.booths.show.officers_list") %>

    - -
    - <%= t("admin.booths.show.no_officers") %> -
    - - -<%= link_to t("admin.booths.show.assign_officer"), "#", class: "button success" %> +<% if @booth.officers.empty? %> +
    + <%= t("admin.booths.show.no_officers") %> +
    +<% end %>
    - - <%# f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %> + <%= form_for @booth, url: admin_poll_booth_path(@poll, @booth) do |f| %> - <%# f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %> - <%# b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %> - <%# end %> + <%= f.label :officer_ids, t("admin.spending_proposals.edit.assigned_valuators") %> + <%= f.collection_check_boxes :officer_ids, @officers, :id, :email do |b| %> + <% b.label { b.check_box + truncate(officer_label(b.object), length: 60) } %> + <% end %> + + <%= f.submit t("admin.booths.show.assign_officer"), class: "button success" %> + <% end %>
    - - <%# @officers.each do |officer| %> - +
    + <% @booth.officers.each do |officer| %> + - <%# end %> + <% end %>
    - <%# officer.name %> - Admin + <%= officer.name %> - admin@consul.dev - <%# officer.email %> + <%= officer.email %> <%= link_to t('admin.poll_officers.officer.delete'), "#", class: "button hollow alert" %> @@ -53,5 +51,5 @@ %>
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index ef294262d..c4a94a86e 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -208,7 +208,7 @@ en: location: "Location" assign_officer: "Assign officer" officers_list: "List of officers" - no_officers: "There is no officers in this booth." + no_officers: "There are no officers assigned to this booth" officials: edit: destroy: Remove 'Official' status diff --git a/db/migrate/20160928113143_create_officing_booths.rb b/db/migrate/20160928113143_create_officing_booths.rb new file mode 100644 index 000000000..00483fe00 --- /dev/null +++ b/db/migrate/20160928113143_create_officing_booths.rb @@ -0,0 +1,9 @@ +class CreateOfficingBooths < ActiveRecord::Migration + def change + create_table :poll_officing_booths do |t| + t.belongs_to :officer + t.belongs_to :booth + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 2da00cfe2..313c6d1f1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -280,8 +280,11 @@ ActiveRecord::Schema.define(version: 20161102133838) do t.integer "user_id" end - create_table "poll_officers", force: :cascade do |t| - t.integer "user_id" + create_table "poll_officing_booths", force: :cascade do |t| + t.integer "officer_id" + t.integer "booth_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "poll_voters", force: :cascade do |t| diff --git a/spec/factories.rb b/spec/factories.rb index 2ef46540e..b88af100c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -267,6 +267,18 @@ FactoryGirl.define do sequence(:name) { |n| "Poll #{n}" } end +<<<<<<< HEAD +======= + factory :poll_officer, class: 'Poll::Officer' do + user + end + + factory :officing_booth, class: 'Poll::OfficingBooth' do + association :officer, factory: :poll_officer + association :booth, factory: :poll_booth + end + +>>>>>>> assigns officers to booths factory :poll_booth, class: 'Poll::Booth' do sequence(:name) { |n| "Booth #{n}" } sequence(:location) { |n| "Street #{n}" } diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb index ed9ec545d..981b17f13 100644 --- a/spec/features/admin/poll/officers_spec.rb +++ b/spec/features/admin/poll/officers_spec.rb @@ -1,12 +1,13 @@ require 'rails_helper' feature 'Admin poll officers' do + background do @admin = create(:administrator) @user = create(:user, username: 'Pedro Jose Garcia') @officer = create(:poll_officer) login_as(@admin.user) - visit admin_poll_officers_path + visit admin_officers_path end scenario 'Index' do @@ -15,7 +16,7 @@ feature 'Admin poll officers' do expect(page).to_not have_content @user.name end - scenario 'Create poll officer', :js do + scenario 'Create', :js do fill_in 'email', with: @user.email click_button 'Search' @@ -26,11 +27,133 @@ feature 'Admin poll officers' do end end - scenario 'Delete poll officer' do + scenario 'Delete' do click_link 'Delete' within("#officers") do expect(page).to_not have_content @officer.name end end + + context "Booth" do + + scenario 'No officers assigned to booth' do + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booth_path(poll, booth) + + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 0 + end + + expect(page).to have_content "There are no officers assigned to this booth" + end + + scenario "Assigned to booth" do + john = create(:poll_officer) + isabel = create(:poll_officer) + eve = create(:poll_officer) + + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + officing_booth1 = create(:officing_booth, officer: john, booth: booth) + officing_booth2 = create(:officing_booth, officer: isabel, booth: booth) + + visit admin_poll_booth_path(poll, booth) + + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 2 + expect(page).to have_content john.name + expect(page).to have_content isabel.name + + expect(page).to_not have_content eve.name + end + + expect(page).to_not have_content "There are no officers assigned to this booth" + end + + scenario 'Assign to booth' do + john = create(:poll_officer) + isabel = create(:poll_officer) + + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + visit admin_poll_booth_path(poll, booth) + + check "#{john.name} - #{john.email}" + click_button "Assign officer" + + expect(page).to have_content "Booth updated successfully." + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content john.name + end + end + + scenario "Unassign from booth" do + john = create(:poll_officer) + isabel = create(:poll_officer) + + poll = create(:poll) + booth = create(:poll_booth, poll: poll) + + officing_booth = create(:officing_booth, officer: john, booth: booth) + officing_booth = create(:officing_booth, officer: isabel, booth: booth) + + visit admin_poll_booth_path(poll, booth) + + uncheck "#{john.name} - #{john.email}" + click_button "Assign officer" + + expect(page).to have_content "Booth updated successfully." + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content isabel.name + + expect(page).to_not have_content john.name + end + end + + scenario "Assigned multiple officers to different booths" do + john = create(:poll_officer) + isabel = create(:poll_officer) + eve = create(:poll_officer) + peter = create(:poll_officer) + + poll1 = create(:poll) + poll2 = create(:poll) + + booth1 = create(:poll_booth, poll: poll1) + booth2 = create(:poll_booth, poll: poll1) + booth3 = create(:poll_booth, poll: poll2) + + officing_booth = create(:officing_booth, officer: john, booth: booth1) + officing_booth = create(:officing_booth, officer: isabel, booth: booth1) + officing_booth = create(:officing_booth, officer: eve, booth: booth2) + officing_booth = create(:officing_booth, officer: peter, booth: booth3) + + visit admin_poll_booth_path(poll1, booth1) + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 2 + expect(page).to have_content john.name + expect(page).to have_content isabel.name + end + + visit admin_poll_booth_path(poll1, booth2) + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content eve.name + end + + visit admin_poll_booth_path(poll2, booth3) + within("#assigned_officers") do + expect(page).to have_css ".officer", count: 1 + expect(page).to have_content peter.name + end + end + end + end \ No newline at end of file From 70752e217d13b7515b6a718152e3eee76cf2fc53 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 14 Oct 2016 19:00:58 +0200 Subject: [PATCH 098/523] adds styles for offering voters views --- app/views/officing/dashboard/index.html.erb | 1 - app/views/officing/voters/new.html.erb | 21 +++++++++++++++- app/views/officing/voters/show.html.erb | 26 +++++++++++++++++++- config/locales/officing.en.yml | 18 ++++++++++++-- config/locales/officing.es.yml | 27 +++++++++++++++++++-- 5 files changed, 86 insertions(+), 7 deletions(-) diff --git a/app/views/officing/dashboard/index.html.erb b/app/views/officing/dashboard/index.html.erb index cf014d719..861a39b1a 100644 --- a/app/views/officing/dashboard/index.html.erb +++ b/app/views/officing/dashboard/index.html.erb @@ -2,5 +2,4 @@

    <%= t("officing.dashboard.index.title") %>

    <%= t("officing.dashboard.index.info") %>

    - diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 0fb4c6bc3..37edfd788 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -1 +1,20 @@ -voters new +

    <%= t("officing.voters.new.title") %>

    + +
    +
    +
    + + + + + + "> + + " class="button"> +
    +
    +
    diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb index fd8c83123..3de9d9651 100644 --- a/app/views/officing/voters/show.html.erb +++ b/app/views/officing/voters/show.html.erb @@ -1 +1,25 @@ -voters show \ No newline at end of file +

    <%= t("officing.voters.show.title") %>

    + + + +
    + <%= t("officing.voters.show.error_verifying_census") %> +
    + + + +
    + <%= t("officing.voters.show.error_already_voted") %> +
    + + + +
    + <%= t("officing.voters.show.success") %> +
    + +
    +
    + " class="button success expanded"> +
    +
    diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index 532d18498..c8989dfc6 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -6,5 +6,19 @@ en: title: Poll officing info: Here you can validate user documents and store voting results menu: - voters: Validate citizen document - results: Store voting results \ No newline at end of file + voters: Validate document + results: Store results + voters: + new: + title: Validate document + document_number: Document number + document_type: + passport: Passport + residence_card: Residence card + spanish_id: DNI + document_type_label: Document type + submit: Validate document + show: + title: Validate document + error_verifying_census: "The Census was unable to verify your information." + error_already_voted: "La persona asociada al documento ya ha participado en la votación." \ No newline at end of file diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index baa60b106..8ab0dc384 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -6,5 +6,28 @@ es: title: Presidir mesa de votaciones info: Aquí puedes validar documentos de ciudadanos y guardar los resultados de las urnas menu: - voters: Validar documento de identidad - results: Guardar resultados de la votación \ No newline at end of file + voters: Validar documento + results: Guardar resultados + voters: + new: + title: Validar documento + document_number: Número de documento + document_type: + passport: Pasaporte + residence_card: Tarjeta de residencia + spanish_id: DNI + document_type_label: Tipo de documento + submit: Validar documento + show: + title: Validar documento + error_verifying_census: "El Padrón no pudo verificar tu información." + error_already_voted: "La persona asociada al documento ya ha participado en la votación." + success: "La persona asociada al documento puede participar en la votación." + submit: Validar voto + results: + index: + title: "Resultados de la votación" + new: + title: "Añadir resultados" + show: + title: "Resultados" \ No newline at end of file From 1a56d5bbe6dd954e2341cdaf73cfcd91d57f2b63 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Oct 2016 16:42:50 +0200 Subject: [PATCH 099/523] adds styles to officing voters views --- app/assets/stylesheets/admin.scss | 4 ++ app/views/officing/_menu.html.erb | 2 +- app/views/officing/results/index.html.erb | 55 ++++++++++++++++++++++- app/views/officing/results/new.html.erb | 39 +++++++++++++++- app/views/officing/results/show.html.erb | 51 ++++++++++++++++++++- app/views/officing/voters/new.html.erb | 2 +- app/views/officing/voters/show.html.erb | 7 ++- config/locales/officing.en.yml | 24 +++++++++- config/locales/officing.es.yml | 19 ++++++-- 9 files changed, 191 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 4968983f0..ee16c798c 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -42,6 +42,10 @@ body.admin { th { text-align: left; + + &.text-center { + text-align: center; + } } tr { diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb index 81734d99f..f051b5940 100644 --- a/app/views/officing/_menu.html.erb +++ b/app/views/officing/_menu.html.erb @@ -14,5 +14,5 @@ <%= t("officing.menu.results") %> <% end %>
  • - + diff --git a/app/views/officing/results/index.html.erb b/app/views/officing/results/index.html.erb index 8e9faa1ab..8e50de625 100644 --- a/app/views/officing/results/index.html.erb +++ b/app/views/officing/results/index.html.erb @@ -1 +1,54 @@ -results index \ No newline at end of file +

    <%= t("officing.results.index.title") %>

    + +
    +
    + +
    + +
    + +
    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%= t("officing.shared.booth") %><%= t("officing.shared.date") %><%= t("officing.shared.officer") %><%= t("officing.shared.votes_number") %>
    <%= link_to "Urna Moncloa (1)", officing_poll_result_path(Poll.last, 1) %>14/10/2016Officer Name (officer@email.com)124
    <%= link_to "Urna Cahamartín (6)", officing_poll_result_path(Poll.last, 1) %>17/10/2016Other Officer (otherofficer@email.com)350
    <%= t("officing.results.index.total_votes") %>474
    diff --git a/app/views/officing/results/new.html.erb b/app/views/officing/results/new.html.erb index bb40dff9e..178efbadd 100644 --- a/app/views/officing/results/new.html.erb +++ b/app/views/officing/results/new.html.erb @@ -1 +1,38 @@ -results new \ No newline at end of file +

    <%= t("officing.results.new.title") %>

    + +
    + +
    +
    + + +
    + +
    + + +
    +
    + +
    +
    + + +
    +
    + +
    + +
    +
    + + "> +
    +
    + +
    +
    + " class="button expanded"> +
    +
    +
    diff --git a/app/views/officing/results/show.html.erb b/app/views/officing/results/show.html.erb index b3ca8e29c..4c7b88e00 100644 --- a/app/views/officing/results/show.html.erb +++ b/app/views/officing/results/show.html.erb @@ -1 +1,50 @@ -results show \ No newline at end of file +<%= render 'shared/back_link' %> + +

    <%= t("officing.results.show.title", booth: "Booth Name (1)") %>

    + +
    +
    + +
    + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    <%= t("officing.shared.date") %><%= t("officing.shared.officer") %><%= t("officing.shared.votes_number") %>
    14/10/2016Officer Name (officer@email.com)124
    17/10/2016Other Officer (otherofficer@email.com)350
    18/10/2016Officer number 3 (officer3@email.com)100
    <%= t("officing.results.index.total_votes") %>574
    diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 37edfd788..2042f7acb 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -1,7 +1,7 @@

    <%= t("officing.voters.new.title") %>

    -
    +
    diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb index 3de9d9651..523e0e0d4 100644 --- a/app/views/officing/voters/show.html.erb +++ b/app/views/officing/voters/show.html.erb @@ -15,7 +15,7 @@
    - <%= t("officing.voters.show.success") %> + <%= t("officing.voters.show.can_participate") %>
    @@ -23,3 +23,8 @@ " class="button success expanded">
    + + +
    + <%= t("officing.voters.show.success") %> +
    \ No newline at end of file diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index c8989dfc6..20cd8fcfc 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -20,5 +20,25 @@ en: submit: Validate document show: title: Validate document - error_verifying_census: "The Census was unable to verify your information." - error_already_voted: "La persona asociada al documento ya ha participado en la votación." \ No newline at end of file + error_verifying_census: "The Census was unable to verify the information of this document." + error_already_voted: "The person associated with the document has already participated in the vote." + can_participate: "The person associated with the document can participate in the vote." + submit: Validate vote + success: "Vote validated correctly." + results: + index: + title: "Vote results" + total_votes: "Total number of votes" + new: + title: Save results + submit: Save + show: + title: "%{booth} results" + shared: + filter_booth: All booths + filter_date: All dates + filter_officer: All officers + booth: Booth + date: Date + officer: Officer + votes_number: Number of votes diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index 8ab0dc384..e187365f1 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -20,14 +20,25 @@ es: submit: Validar documento show: title: Validar documento - error_verifying_census: "El Padrón no pudo verificar tu información." + error_verifying_census: "El Padrón no pudo verificar la información de este documento." error_already_voted: "La persona asociada al documento ya ha participado en la votación." - success: "La persona asociada al documento puede participar en la votación." + can_participate: "La persona asociada al documento puede participar en la votación." submit: Validar voto + success: "Voto validado correctamente." results: index: title: "Resultados de la votación" + total_votes: "Número total de votos" new: - title: "Añadir resultados" + title: Guardar resultados + submit: Guardar show: - title: "Resultados" \ No newline at end of file + title: "Resultados de %{booth}" + shared: + filter_booth: Todas las urnas + filter_date: Todas las fechas + filter_officer: Todos los presidentes de mesa + booth: Urna + date: Fecha + officer: Presidente de mesa + votes_number: Número de votos From 96cf578259f0a2cc5be930828414c3233cbdea2f Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Oct 2016 16:43:11 +0200 Subject: [PATCH 100/523] add officing to i18n tasks --- config/i18n-tasks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index edaaa0958..2008f02e1 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -32,6 +32,7 @@ data: - config/locales/devise_views.%{locale}.yml - config/locales/responders.%{locale}.yml - config/locales/kaminari.%{locale}.yml + - config/locales/officing.%{locale}.yml # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom: # `i18n-tasks normalize -p` will force move the keys according to these rules From 0dd122833a6f71403af30f5c6be2873bf3d145b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 19 Oct 2016 13:44:05 +0200 Subject: [PATCH 101/523] removes booths link from admin menu --- app/views/admin/_menu.html.erb | 8 ---- spec/features/admin/poll/booths_spec.rb | 57 +++---------------------- 2 files changed, 5 insertions(+), 60 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 0661a3bb6..11e46814d 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -95,14 +95,6 @@ <% end %> - <% if Poll.any? %> -
  • > - <%= link_to admin_poll_booths_url(Poll.last) do %> - <%= t('admin.menu.booths') %> - <% end %> -
  • - <% end %> -
  • > <%= link_to admin_activity_path do %> <%= t('admin.menu.activity') %> diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb index ad46c67fb..eff653dfe 100644 --- a/spec/features/admin/poll/booths_spec.rb +++ b/spec/features/admin/poll/booths_spec.rb @@ -13,32 +13,24 @@ feature 'Admin booths' do visit admin_root_path within('#side_menu') do - click_link "Booths" + click_link "Polls" end + click_link poll.name + expect(page).to have_content "There are no booths in this poll" end - scenario 'No link to booths when no polls' do - Poll.destroy_all - - visit admin_root_path - - within('#side_menu') do - expect(page).to_not have_link "Booths" - end - end - scenario 'Index' do 3.times { create(:poll_booth, poll: poll) } visit admin_root_path within('#side_menu') do - click_link "Booths" + click_link "Polls" end - expect(page).to have_css ".booth", count: 3 + click_link poll.name booths = Poll::Booth.all booths.each do |booth| @@ -50,45 +42,6 @@ feature 'Admin booths' do expect(page).to_not have_content "There are no booths" end - scenario "Index default to last poll" do - poll1 = create(:poll) - poll2 = create(:poll) - - booth1 = create(:poll_booth, poll: poll1) - booth2 = create(:poll_booth, poll: poll2) - - visit admin_root_path - - within('#side_menu') do - click_link "Booths" - end - - expect(page).to have_css ".booth", count: 1 - expect(page).to have_content booth2.name - expect(page).to_not have_content booth1.name - end - - scenario "Index select poll", :js do - poll1 = create(:poll) - poll2 = create(:poll) - - booth1 = create(:poll_booth, poll: poll1) - booth2 = create(:poll_booth, poll: poll2) - - visit admin_root_path - - within('#side_menu') do - click_link "Booths" - end - - select poll1.name, from: "poll_id" - - expect(page).to have_content "List of booths of poll #{poll1.name}" - expect(page).to have_css ".booth", count: 1 - expect(page).to have_content booth1.name - expect(page).to_not have_content booth2.name - end - scenario 'Show' do booth = create(:poll_booth, poll: poll) From 6e3da012e5adedcdf8e3a4b0fe86a3a9871549e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 12:31:06 +0200 Subject: [PATCH 102/523] removes unused i18n key --- config/locales/admin.en.yml | 1 - config/locales/admin.es.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index c4a94a86e..6c42ac23e 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -106,7 +106,6 @@ en: valuators: Valuators poll_officers: Poll officers polls: Polls - booths: Booths officials: Officials organizations: Organisations settings: Configuration settings diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 48dfe2959..55991e056 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -106,7 +106,6 @@ es: valuators: Evaluadores poll_officers: Presidentes de mesa polls: Votaciones - booths: Urnas officials: Cargos públicos organizations: Organizaciones settings: Configuración global From b8302b6fa86ea3c847910ab279e423980e94b755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 16:14:03 +0200 Subject: [PATCH 103/523] adds dates to polls --- db/migrate/20161020112156_add_dates_to_polls.rb | 6 ++++++ db/schema.rb | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20161020112156_add_dates_to_polls.rb diff --git a/db/migrate/20161020112156_add_dates_to_polls.rb b/db/migrate/20161020112156_add_dates_to_polls.rb new file mode 100644 index 000000000..d504930ae --- /dev/null +++ b/db/migrate/20161020112156_add_dates_to_polls.rb @@ -0,0 +1,6 @@ +class AddDatesToPolls < ActiveRecord::Migration + def change + add_column :polls, :starts_at, :datetime + add_column :polls, :ends_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index 313c6d1f1..b5891df82 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -294,7 +294,9 @@ ActiveRecord::Schema.define(version: 20161102133838) do end create_table "polls", force: :cascade do |t| - t.string "name" + t.string "name" + t.datetime "starts_at" + t.datetime "ends_at" end create_table "proposal_notifications", force: :cascade do |t| From 76a4f420eb6e12ad1d22acf77d075b5520547516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 16:25:02 +0200 Subject: [PATCH 104/523] changes menu name --- config/locales/admin.es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 55991e056..024f6abe2 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -105,7 +105,7 @@ es: moderators: Moderadores valuators: Evaluadores poll_officers: Presidentes de mesa - polls: Votaciones + polls: Votaciones físicas officials: Cargos públicos organizations: Organizaciones settings: Configuración global From 7b3c9b725cf2634778e4ca6d7a4e13e954835ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 20 Oct 2016 16:25:36 +0200 Subject: [PATCH 105/523] fights a flaky spec --- spec/features/account_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/features/account_spec.rb b/spec/features/account_spec.rb index d1c547185..5561e89d4 100644 --- a/spec/features/account_spec.rb +++ b/spec/features/account_spec.rb @@ -112,7 +112,11 @@ feature 'Account' do end scenario 'Errors editing credentials' do - visit account_path + visit root_path + + click_link "My account" + + expect(current_path).to eq(account_path) click_link 'Change my credentials' click_button 'Update' From c1336ccc139251d48b03d40921e6064f3daa69f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 27 Oct 2016 15:52:07 +0200 Subject: [PATCH 106/523] adds fields and i18n keys to admin poll form --- app/views/admin/poll/polls/_form.html.erb | 16 ++++++++++++++-- config/i18n-tasks.yml | 1 + config/locales/admin.en.yml | 12 ++++-------- config/locales/admin.es.yml | 14 +++++--------- config/locales/responders.es.yml | 4 ++-- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 77961912c..9926c679a 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -2,8 +2,20 @@
    <%= f.text_field :name, - placeholder: t('admin.polls.new.name'), - label: t("admin.polls.new.name") %> + placeholder: t('admin.polls.form.name'), + label: t("admin.polls.form.name") %> +
    +
    + +
    +
    + + +
    + +
    + +
    diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 2008f02e1..0b1e932df 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -120,6 +120,7 @@ ignore_unused: - 'admin.activity.show.filter*' - 'admin.comments.index.hidden_*' - 'admin.settings.index.features.*' + - 'admin.polls.*.submit_button' - 'moderation.comments.index.filter*' - 'moderation.comments.index.order*' - 'moderation.debates.index.filter*' diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 6c42ac23e..1d80aa4cd 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -160,18 +160,14 @@ en: status: "Status" new: title: "New poll" - name: "Name" - reference: "Reference number" - open_date: "Open date" - close_date: "Close date" submit_button: "Create poll" edit: title: "Edit poll" - name: "Name" - reference: "Reference number" - open_date: "Open date" - close_date: "Close date" submit_button: "Update poll" + form: + name: "Name" + starts_at: "Open date" + ends_at: "Close date" show: no_booths: "There are no booths in this poll." add_booth: "Add booth" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 024f6abe2..cce743dcc 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -105,7 +105,7 @@ es: moderators: Moderadores valuators: Evaluadores poll_officers: Presidentes de mesa - polls: Votaciones físicas + polls: Votaciones officials: Cargos públicos organizations: Organizaciones settings: Configuración global @@ -160,18 +160,14 @@ es: status: "Estado" new: title: "Nueva votación" - name: "Nombre" - reference: "Número de referencia" - open_date: "Fecha de apertura" - close_date: "Fecha de cierre" submit_button: "Crear votación" edit: title: "Editar votación" - name: "Nombre" - reference: "Número de referencia" - open_date: "Fecha de apertura" - close_date: "Fecha de cierre" submit_button: "Actualizar votación" + form: + name: "Nombre" + starts_at: "Fecha de apertura" + ends_at: "Fecha de cierre" show: no_booths: "No hay urnas en esta votación." add_booth: "Añadir urna" diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index 105b00903..54c4c7035 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -6,7 +6,7 @@ es: notice: "%{resource_name} creado correctamente." debate: "Debate creado correctamente." direct_message: "Tu mensaje ha sido enviado correctamente." - poll: "Votación presencial creada correctamente." + poll: "Votación creada correctamente." poll_booth: "Urna creada correctamente." proposal: "Propuesta creada correctamente." proposal_notification: "Tu message ha sido enviado correctamente." @@ -17,7 +17,7 @@ es: notice: "%{resource_name} actualizado correctamente." debate: "Debate actualizado correctamente." proposal: "Propuesta actualizada correctamente." - poll: "Votación presencial actualizada correctamente." + poll: "Votación actualizada correctamente." poll_booth: "Urna actualizada correctamente." spending_proposal: "Propuesta de inversión actualizada correctamente." destroy: From 127cbcc5c7623cc3f23bf8afe94815b335e08e2c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:38:41 +0100 Subject: [PATCH 107/523] adds dev seeds for polls and poll questions --- db/dev_seeds.rb | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 51f46b3c6..2c2f106ee 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -362,7 +362,32 @@ end puts "Creating polls" 3.times.each_with_index do |i| - Poll.create(name: "Poll #{i}") + starts_at = rand(2.months.ago .. 2.months.from_now) + ends_at = starts_at + 1.month + + poll = Poll.create(name: "Poll #{i}", + starts_at: starts_at, + ends_at: ends_at) + puts " #{poll.name}" +end + +puts "Creating Poll Questions" + +(1..10).each do |i| + poll = Poll.reorder("RANDOM()").first + author = User.reorder("RANDOM()").first + description = "

    #{Faker::Lorem.paragraphs.join('

    ')}

    " + open_at = rand(2.months.ago .. 2.months.from_now) + question = Poll::Question.create!(author: author, + title: Faker::Lorem.sentence(3).truncate(60), + question: Faker::Lorem.sentence(3) + "?", + summary: Faker::Lorem.sentence(3), + description: description, + valid_answers: Faker::Lorem.words(3).join(', '), + poll: poll, + geozones: Geozone.reorder("RANDOM()").limit(3), + all_geozones: [true, false].sample) + puts " #{question.title}" end 10.times.each_with_index do |i| From ac58f30498d8be63e36afd47f556e9a992e3fcc9 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:39:20 +0100 Subject: [PATCH 108/523] removes proposal ballots --- .../proposal_ballots_controller.rb | 8 ----- .../_successfull_proposal.html.erb | 13 ------- app/views/proposal_ballots/index.html.erb | 35 ------------------- app/views/shared/_subnavigation.html.erb | 2 +- config/routes.rb | 2 -- 5 files changed, 1 insertion(+), 59 deletions(-) delete mode 100644 app/controllers/proposal_ballots_controller.rb delete mode 100644 app/views/proposal_ballots/_successfull_proposal.html.erb delete mode 100644 app/views/proposal_ballots/index.html.erb diff --git a/app/controllers/proposal_ballots_controller.rb b/app/controllers/proposal_ballots_controller.rb deleted file mode 100644 index 4e3e99671..000000000 --- a/app/controllers/proposal_ballots_controller.rb +++ /dev/null @@ -1,8 +0,0 @@ -class ProposalBallotsController < ApplicationController - skip_authorization_check - - def index - @proposal_ballots = Proposal.successfull.sort_by_confidence_score - end - -end diff --git a/app/views/proposal_ballots/_successfull_proposal.html.erb b/app/views/proposal_ballots/_successfull_proposal.html.erb deleted file mode 100644 index 870e61605..000000000 --- a/app/views/proposal_ballots/_successfull_proposal.html.erb +++ /dev/null @@ -1,13 +0,0 @@ -
    -

    <%= link_to proposal.title, proposal %>

    -
    - <% if proposal.author.hidden? || proposal.author.erased? %> - <%= t("proposals.show.author_deleted") %> - <% else %> - <%= proposal.author.name %> - <% end %> - -  •  - <%= l proposal.created_at.to_date %> -
    -
    diff --git a/app/views/proposal_ballots/index.html.erb b/app/views/proposal_ballots/index.html.erb deleted file mode 100644 index 00a07fb9e..000000000 --- a/app/views/proposal_ballots/index.html.erb +++ /dev/null @@ -1,35 +0,0 @@ -
    -
    -
    -

    - <%= t("proposal_ballots.title") %> -

    -

    - <%= t("proposal_ballots.description_html").html_safe %> -

    -
    - -
    -

    <%= t("proposal_ballots.date_title") %>

    -

    <%= t("proposal_ballots.date") %>

    -
    -
    -
    - -
    -
    -
    - <% if @proposal_ballots.present? %> -
    - <% @proposal_ballots.each do |proposal_for_vote| %> - <%= render "successfull_proposal", proposal: proposal_for_vote %> - <% end %> -
    - <% else %> -

    - <%= t("proposal_ballots.nothing_to_vote") %> -

    - <% end %> -
    -
    -
    diff --git a/app/views/shared/_subnavigation.html.erb b/app/views/shared/_subnavigation.html.erb index 9d87a0294..f1334b85c 100644 --- a/app/views/shared/_subnavigation.html.erb +++ b/app/views/shared/_subnavigation.html.erb @@ -9,7 +9,7 @@ <%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if controller_name == "proposals"), accesskey: "p" %>
  • - <%= link_to t("layouts.header.proposal_ballot"), proposal_ballots_path, class: ("active" if controller_name == "proposal_ballots"), accesskey: "v" %> + <%= link_to t("layouts.header.proposal_ballot"), polls_path, class: ("active" if controller_name == "proposal_ballots"), accesskey: "v" %>
  • <% if feature?(:spending_proposals) %>
  • diff --git a/config/routes.rb b/config/routes.rb index 95e5a87b1..69a613bdd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -61,8 +61,6 @@ Rails.application.routes.draw do end end - resources :proposal_ballots, only: [:index] - resources :comments, only: [:create, :show], shallow: true do member do post :vote From 6fe965a9b873f123704c6f2cceeeab255159966c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:41:29 +0100 Subject: [PATCH 109/523] adds question's show --- app/controllers/polls/questions_controller.rb | 12 ++++ app/models/abilities/everyone.rb | 1 + app/views/polls/questions/show.html.erb | 55 +++++++++++++++++++ app/views/polls/show.html.erb | 4 +- config/routes.rb | 2 +- 5 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 app/views/polls/questions/show.html.erb diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index dcf459485..07d7aa28f 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -3,6 +3,18 @@ class Polls::QuestionsController < ApplicationController load_and_authorize_resource :poll load_and_authorize_resource :question, class: 'Poll::Question', through: :poll + has_filters %w{opened expired incoming} + has_orders %w{most_voted newest oldest}, only: :show + + def show + @commentable = @question.proposal.present? ? @question.proposal : @question + @comment_tree = CommentTree.new(@commentable, params[:page], @current_order) + set_comment_flags(@comment_tree.comments) + + #@question_answer = @question.answers.where(author_id: current_user.try(:id)).first + @answers_by_question_id = {@question.id => params[:answer]} + end + def answer partial_result = @question.partial_results.find_or_initialize_by(author: current_user, amount: 1, diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb index 8424500a3..d8b7c1da7 100644 --- a/app/models/abilities/everyone.rb +++ b/app/models/abilities/everyone.rb @@ -7,6 +7,7 @@ module Abilities can [:read, :map, :summary], Proposal can :read, Comment can :read, Poll + can :read, Poll::Question can :read, SpendingProposal can :read, Legislation can :read, User diff --git a/app/views/polls/questions/show.html.erb b/app/views/polls/questions/show.html.erb new file mode 100644 index 000000000..e48a65ad0 --- /dev/null +++ b/app/views/polls/questions/show.html.erb @@ -0,0 +1,55 @@ +
    +
    +
    + <%= render "shared/back_link" %> + +

    <%= @question.title %>

    + + <% if @question.proposal.present? %> +
    + <%= link_to t('questions.show.original_proposal'), @question.proposal %> +
    + <% end %> + +

    <%= @question.summary %>

    + +
      + <% @question.geozones.each do |g| %> +
    • <%= g.name %>
    • + <% end %> +
    +
    + +
    +

    + <%= t('questions.show.author') %>
    + <%= link_to @question.author.name, @question.author %> +

    + +

    + <%= t('questions.show.external_url') %>
    + <%# link_to @question.external_url, @question.external_url %> +

    +
    +
    +
    + +
    +
    +

    <%= @question.question %>

    +
    +
    + +
    + <%= render "answers", question: @question %> +
    + +
    +
    +

    <%= t('questions.show.more_info') %>

    + <%= @question.description %> +
    +
    + + +<%= render "comments" %> diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index ad7818a78..d9bfbbd3b 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -27,7 +27,7 @@ <% @answerable_questions.each do |question| %>
    - <%= question.title %> + <%= link_to question.title, poll_question_path(@poll, question) %>
    <%= render 'polls/questions/answers', question: question %> @@ -44,7 +44,7 @@ <% @non_answerable_questions.each do |question| %>
    - <%= question.title %> + <%= link_to question.title, poll_question_path(@poll, question) %>
    <%= render 'polls/questions/answers', question: question %> diff --git a/config/routes.rb b/config/routes.rb index 69a613bdd..0d227717b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -84,7 +84,7 @@ Rails.application.routes.draw do end resources :polls, only: [:show, :index] do - resources :questions, only: [], controller: 'polls/questions' do + resources :questions, only: [:show], controller: 'polls/questions' do post :answer, on: :member end end From b104859da322b4fdb22e66dd9e2d78ed8d8633d3 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:41:52 +0100 Subject: [PATCH 110/523] adds question comments --- app/models/abilities/administrator.rb | 2 +- app/models/abilities/moderator.rb | 2 +- app/models/comment.rb | 4 +-- app/views/polls/questions/_comments.html.erb | 31 ++++++++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 app/views/polls/questions/_comments.html.erb diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index a0e040ab3..79999cd04 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -33,7 +33,7 @@ module Abilities can :mark_featured, Debate can :unmark_featured, Debate - can :comment_as_administrator, [Debate, Comment, Proposal] + can :comment_as_administrator, [Debate, Comment, Proposal, Poll::Question] can [:search, :create, :index, :destroy], ::Moderator can [:search, :create, :index, :summary], ::Valuator diff --git a/app/models/abilities/moderator.rb b/app/models/abilities/moderator.rb index f6c5c5004..634002933 100644 --- a/app/models/abilities/moderator.rb +++ b/app/models/abilities/moderator.rb @@ -5,7 +5,7 @@ module Abilities def initialize(user) self.merge Abilities::Moderation.new(user) - can :comment_as_moderator, [Debate, Comment, Proposal] + can :comment_as_moderator, [Debate, Comment, Proposal, Poll::Question] end end end diff --git a/app/models/comment.rb b/app/models/comment.rb index 47beb5050..b666b354a 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -10,7 +10,7 @@ class Comment < ActiveRecord::Base validates :body, presence: true validates :user, presence: true - validates_inclusion_of :commentable_type, in: ["Debate", "Proposal"] + validates_inclusion_of :commentable_type, in: ["Debate", "Proposal", "Poll::Question"] validate :validate_body_length @@ -95,7 +95,7 @@ class Comment < ActiveRecord::Base end def self.body_max_length - Setting['comments_body_max_length'].to_i + Setting['comments_body_max_length'].to_i end def calculate_confidence_score diff --git a/app/views/polls/questions/_comments.html.erb b/app/views/polls/questions/_comments.html.erb new file mode 100644 index 000000000..a967406aa --- /dev/null +++ b/app/views/polls/questions/_comments.html.erb @@ -0,0 +1,31 @@ +<% cache [locale_and_user_status, @current_order, commentable_cache_key(@commentable), @comment_tree.comments, @comment_tree.comment_authors, @commentable.comments_count, @comment_flags] do %> +
    +
    +
    +

    + <%= t("shared.comments.title") %> + (<%= @commentable.comments_count %>) +

    + + <%= render 'shared/wide_order_selector', i18n_namespace: "comments" %> + + <% if user_signed_in? %> + <%= render 'comments/form', {commentable: @commentable, parent_id: nil, toggeable: false} %> + <% else %> +
    + +
    + <%= t("shared.comments.login_to_comment", + signin: link_to(t("votes.signin"), new_user_session_path), + signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %> +
    + <% end %> + + <% @comment_tree.root_comments.each do |comment| %> + <%= render 'comments/comment', comment: comment %> + <% end %> + <%= paginate @comment_tree.root_comments %> +
    +
    +
    +<% end %> \ No newline at end of file From 348a6dc970022eeb14a2ff13781e72e164822e8e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:42:05 +0100 Subject: [PATCH 111/523] everybody can vote for now --- app/models/poll/question.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 68f0be910..c536fe5a3 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -49,7 +49,8 @@ class Poll::Question < ActiveRecord::Base end def answerable_by?(user) - poll.answerable_by?(user) && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) + true + #poll.answerable_by?(user) && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) end def self.answerable_by(user) From 1dbdabb69a903c44f3107206d682f03c1b4563dc Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:42:35 +0100 Subject: [PATCH 112/523] adds consistency to spacing --- app/models/poll/partial_result.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/models/poll/partial_result.rb b/app/models/poll/partial_result.rb index 202f147bd..3dc432f1c 100644 --- a/app/models/poll/partial_result.rb +++ b/app/models/poll/partial_result.rb @@ -3,7 +3,7 @@ class Poll::PartialResult < ActiveRecord::Base VALID_ORIGINS = %w{ web } belongs_to :question, -> { with_hidden } - belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' + belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' validates :question, presence: true validates :author, presence: true @@ -13,6 +13,4 @@ class Poll::PartialResult < ActiveRecord::Base scope :by_author, -> (author_id) { where(author_id: author_id) } scope :by_question, -> (question_id) { where(question_id: question_id) } - - -end +end \ No newline at end of file From bd1a0cf1ff166f1ad14dc9a7ac2015bd385456e7 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 16 Nov 2016 19:42:45 +0100 Subject: [PATCH 113/523] removes placeholder view --- app/views/poll/voters/new.html.erb | 1 - 1 file changed, 1 deletion(-) delete mode 100644 app/views/poll/voters/new.html.erb diff --git a/app/views/poll/voters/new.html.erb b/app/views/poll/voters/new.html.erb deleted file mode 100644 index 596b8769c..000000000 --- a/app/views/poll/voters/new.html.erb +++ /dev/null @@ -1 +0,0 @@ -new.html.erb \ No newline at end of file From d9ad658758609f2fc914ded0117a2d6969a08d50 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 17 Nov 2016 09:30:42 +0100 Subject: [PATCH 114/523] adds admin interface for poll questions --- .../admin/poll/questions_controller.rb | 57 +++++++++++++++++++ app/controllers/polls/questions_controller.rb | 2 +- app/models/abilities/administrator.rb | 4 ++ app/views/admin/_menu.html.erb | 8 +++ app/views/admin/poll/questions/_form.html.erb | 43 ++++++++++++++ app/views/admin/poll/questions/edit.html.erb | 5 ++ app/views/admin/poll/questions/index.html.erb | 22 +++++++ app/views/admin/poll/questions/new.html.erb | 5 ++ config/locales/activerecord.es.yml | 7 +++ config/locales/admin.en.yml | 10 ++++ config/locales/admin.es.yml | 10 ++++ config/locales/en.yml | 53 ++++++++++++----- config/locales/es.yml | 53 +++++++++++++---- config/locales/responders.en.yml | 3 +- config/locales/responders.es.yml | 3 +- config/locales/settings.en.yml | 2 + config/locales/settings.es.yml | 1 + config/routes.rb | 3 +- db/dev_seeds.rb | 1 + 19 files changed, 263 insertions(+), 29 deletions(-) create mode 100644 app/controllers/admin/poll/questions_controller.rb create mode 100644 app/views/admin/poll/questions/_form.html.erb create mode 100644 app/views/admin/poll/questions/edit.html.erb create mode 100644 app/views/admin/poll/questions/index.html.erb create mode 100644 app/views/admin/poll/questions/new.html.erb diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb new file mode 100644 index 000000000..25b14251c --- /dev/null +++ b/app/controllers/admin/poll/questions_controller.rb @@ -0,0 +1,57 @@ +class Admin::Poll::QuestionsController < Admin::BaseController + load_and_authorize_resource :question, class: 'Poll::Question' + + before_action :load_geozones, only: [:new, :create, :edit, :update] + + def index + @questions = @questions.page(params[:page]) + end + + def new + @question.valid_answers = I18n.t('questions.default_valid_answers') + proposal = Proposal.find(params[:proposal_id]) if params[:proposal_id].present? + @question.copy_attributes_from_proposal(proposal) + end + + def create + @question.author = @question.proposal.try(:author) || current_user + + if @question.save + redirect_to question_path(@question) + else + render :new + end + end + + def edit + + end + + def update + if @question.update(question_params) + redirect_to question_path(@question), notice: t("flash.actions.save_changes.notice") + else + render :edit + end + end + + def destroy + if @question.destroy + notice = "Question destroyed succesfully" + else + notice = t("flash.actions.destroy.error") + end + redirect_to admin_questions_path, notice: notice + end + + private + + def load_geozones + @geozones = Geozone.all.order(:name) + end + + def question_params + params.require(:poll_question).permit(:title, :question, :summary, :description, :proposal_id, :valid_answers, :geozone_ids => []) + end + +end \ No newline at end of file diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index 07d7aa28f..4ab83332b 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -1,7 +1,7 @@ class Polls::QuestionsController < ApplicationController load_and_authorize_resource :poll - load_and_authorize_resource :question, class: 'Poll::Question', through: :poll + load_and_authorize_resource :question, class: 'Poll::Question'#, through: :poll has_filters %w{opened expired incoming} has_orders %w{most_voted newest oldest}, only: :show diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 79999cd04..14cf86a30 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -43,6 +43,10 @@ module Abilities can :manage, Annotation can [:read, :update, :destroy, :summary], SpendingProposal + + can [:read, :create, :update], Poll::Question + can :destroy, Poll::Question # , comments_count: 0, votes_up: 0 + can [:search, :edit, :update, :create, :index, :destroy], Banner can [:manage], Poll diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 11e46814d..45c450a06 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -35,6 +35,14 @@
  • <% end %> + <% if feature?(:polls) %> +
  • > + <%= link_to admin_questions_path do %> + <%= t("admin.menu.poll_questions") %> + <% end %> +
  • + <% end %> +
  • > <%= link_to admin_banners_path do %> <%= t("admin.menu.banner") %> diff --git a/app/views/admin/poll/questions/_form.html.erb b/app/views/admin/poll/questions/_form.html.erb new file mode 100644 index 000000000..32f16c773 --- /dev/null +++ b/app/views/admin/poll/questions/_form.html.erb @@ -0,0 +1,43 @@ +<%= form_for(@question, url: form_url) do |f| %> + + <%= render 'shared/errors', resource: @question %> + + <%= f.hidden_field :proposal_id %> + +
    + +
    + <%= f.text_field :title, maxlength: Poll::Question.title_max_length %> + + <%= f.text_field :question, maxlength: Poll::Question.question_max_length %> + + <%= f.text_field :valid_answers %> + + <%= f.text_area :summary, rows: 4, maxlength: 200 %> + +
    + <%= f.cktext_area :description, + maxlength: Poll::Question.description_max_length, + ckeditor: { language: I18n.locale } %> +
    + +
    + <%= f.collection_check_boxes(:geozone_ids, @geozones, :id, :name) do |b| %> +
    + <%= b.label do %> + <%= b.check_box + b.text %> + <% end %> +
    + <% end %> +
    + <%# TODO include all link %> + +
    +
    + <%= f.submit(class: "button expanded", value: t("shared.save")) %> +
    +
    +
    +
    + +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/questions/edit.html.erb b/app/views/admin/poll/questions/edit.html.erb new file mode 100644 index 000000000..6c4d24adf --- /dev/null +++ b/app/views/admin/poll/questions/edit.html.erb @@ -0,0 +1,5 @@ +<%= render "shared/back_link" %> + +

    <%= t("admin.questions.edit.title") %>

    + +<%= render "form", form_url: admin_question_path(@question) %> \ No newline at end of file diff --git a/app/views/admin/poll/questions/index.html.erb b/app/views/admin/poll/questions/index.html.erb new file mode 100644 index 000000000..eb0698780 --- /dev/null +++ b/app/views/admin/poll/questions/index.html.erb @@ -0,0 +1,22 @@ +

    <%= t('admin.questions.index.title') %>

    + +<%= link_to t('admin.questions.index.create'), new_admin_question_path, + class: "button success float-right" %> + +<% if @questions.count == 0 %> +
    + <%= t('admin.questions.index.no_questions') %> +
    +<% else %> + + <% @questions.each do |question| %> + + + + + <% end %> +
    <%= link_to question.title, question_path(question) %> + <%= link_to t('shared.edit'), edit_admin_question_path(question), class: "button hollow" %> + <%= link_to t('shared.delete'), admin_question_path(question), class: "button hollow alert", method: :delete %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/questions/new.html.erb b/app/views/admin/poll/questions/new.html.erb new file mode 100644 index 000000000..830492d6d --- /dev/null +++ b/app/views/admin/poll/questions/new.html.erb @@ -0,0 +1,5 @@ +<%= render "shared/back_link" %> + +

    <%= t("admin.questions.new.title") %>

    + +<%= render "form", form_url: admin_questions_path %> \ No newline at end of file diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index a439a6c5c..8ce255739 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -69,6 +69,13 @@ es: external_url: "Enlace a documentación adicional" geozone_id: "Ámbito de actuación" title: "Título" + poll/question: + title: "Título" + question: "Pregunta" + valid_answers: "Posibles respuestas" + summary: "Resumen" + description: "Descripción" + external_url: "Enlace a documentación adicional" errors: models: user: diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 1d80aa4cd..c86f57266 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -95,6 +95,7 @@ en: activity: Moderator activity admin: Admin menu banner: Manage banners + poll_questions: Poll questions debate_topics: Debate topics hidden_comments: Hidden comments hidden_debates: Hidden debates @@ -175,6 +176,15 @@ en: name: "Name" location: "Location" officers: "Officers" + questions: + index: + title: "Questions" + create: "Create question" + no_enquiries: "There are no questions." + edit: + title: "Edit Question" + new: + title: "Create Question" booths: index: title: "List of booths" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index cce743dcc..b579bfec5 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -96,6 +96,7 @@ es: admin: Menú de administración banner: Gestionar banners debate_topics: Temas de debate + poll_questions: Preguntas ciudadanas hidden_comments: Comentarios ocultos hidden_debates: Debates ocultos hidden_proposals: Propuestas ocultas @@ -175,6 +176,15 @@ es: name: "Nombre" location: "Ubicación" officers: "Presidentes de mesa" + questions: + index: + title: "Preguntas ciudadanas" + create: "Crear pregunta ciudadana" + no_enquiries: "No hay ninguna pregunta ciudadana." + edit: + title: "Editar pregunta ciudadana" + new: + title: "Crear pregunta ciudadana" booths: index: title: "Lista de urnas" diff --git a/config/locales/en.yml b/config/locales/en.yml index 7c9abd2b9..74f267bc3 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -210,7 +210,7 @@ en: open_data: Open data open_gov: Open government proposals: Proposals - proposal_ballot: Voting + polls: Voting see_all: See proposals spending_proposals: Spending proposals legislation: @@ -385,19 +385,40 @@ en: cant_answer_incoming: "This poll has not yet started." cant_answer_expired: "This poll has finished." cant_answer_wrong_geozone: "The following questions are not available in your geozone." - poll_questions: + questions: + create_question: "Create question" default_valid_answers: "Yes, No" - proposal_ballots: - title: "Votings" - description_html: "The following citizen proposals that have reached the required supports and will be voted." - date_title: "Dates of participation" - date: "Soon we'll announce the date of vote these proposals." - successfull: "This proposal has reached the required supports and will be voted in the %{voting}." - voting: "next voting" - featured_title: "#NextVoting" - nothing_to_vote: "There is nothing to vote at the moment." - info: "New proposals that have reached the voting phase." - button: "I want to decide" + index: + filters: + opened: "Open" + incoming: "Incoming" + expired: "Expired" + title: "Enquiries" + description_html: "The following citizen proposals that have reached the required supports and will be voted." + dates: "From %{open_at} to %{closed_at}" + no_enquiries_opened: "There aren't opened enquiries." + no_enquiries_expired: "There aren't expired enquiries." + no_enquiries_incoming: "There aren't incoming enquiries." + show: + original_proposal: "Original proposal" + author: "Created by" + dates_title: "Participation dates" + dates: "From %{open_at} to %{closed_at}" + external_url: "Additional documentation" + more_info: "More information" + not_logged_in: "You must %{signin} or %{signup} to participate." + signin: Sign in + signup: Sign up + cant_answer_verify_html: "You must %{verify_link} in order to answer." + verify_link: "verify your account" + cant_answer_incoming: "This question has not yet started." + cant_answer_expired: "This question has finished." + cant_answer_wrong_geozone: "This question is not available on your geozone." + vote_answer: "Vote %{answer}" + voted: "You have voted %{answer}" + banner: + featured_title: "#NextVoting" + info: "New proposals that have reached the voting phase." proposal_notifications: new: title: "Send message" @@ -409,6 +430,12 @@ en: show: back: "Go back to my activity" shared: + edit: 'Edit' + save: 'Save' + delete: 'Delete' + comments: + title: 'Comments' + login_to_comment: 'You must %{signin} or %{signup} to leave a comment.' advanced_search: author_type: 'By author category' author_type_blank: 'Select a category' diff --git a/config/locales/es.yml b/config/locales/es.yml index 80541466b..c8ac24ed2 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -210,7 +210,7 @@ es: open_data: Datos abiertos open_gov: Gobierno %{open} proposals: Propuestas - proposal_ballot: Votaciones + poll_questions: Votaciones see_all: Ver propuestas spending_proposals: Presupuestos ciudadanos legislation: @@ -375,17 +375,40 @@ es: update: form: submit_button: Guardar cambios - proposal_ballots: - title: "Votaciones" - description_html: "Las siguientes propuestas ciudadanas han alcanzado el número de apoyos necesarios y pasarán a votación." - date_title: "Fechas de participación" - date: "En breve anunciaremos la fecha de votación de estas propuestas." - successfull: "Esta propuesta ha alcanzado los apoyos necesarios y pasará a la %{voting}." - voting: "próxima votación" - featured_title: "#PróximaVotación" - nothing_to_vote: "No hay nada que votar en este momento." - info: "Nuevas propuestas ciudadanas han llegado a la fase de votación." - button: "Quiero decidir" + questions: + create_enquiry: "Crear votación" + default_valid_answers: "Sí, No" + index: + filters: + opened: "Abiertas" + incoming: "Próximamente" + expired: "Terminadas" + title: "Votaciones" + description_html: "Las siguientes propuestas ciudadanas han alcanzado el número de apoyos necesarios y pasarán a votación." + dates: "Desde el %{open_at} hasta el %{closed_at}" + no_enquiries_opened: "No hay votaciones abiertas." + no_enquiries_expired: "No hay votaciones terminadas." + no_enquiries_incoming: "No hay votaciones próximamente." + show: + original_proposal: "Propuesta original" + author: "Creado por" + dates_title: "Fechas de participación" + dates: "Desde el %{open_at} hasta el %{closed_at}" + external_url: "Documentación adicional" + more_info: "Más información" + not_logged_in: "Necesitas %{signin} o %{signup} para participar." + signin: iniciar sesión + signup: registrarte + cant_answer_verify_html: "Por favor %{verify_link} para poder responder." + verify_link: "verifica tu cuenta" + cant_answer_incoming: "Esta votación todavía no ha comenzado." + cant_answer_expired: "Esta votación ha terminado." + cant_answer_wrong_geozone: "Esta votación no está disponible en tu zona." + vote_answer: "Votar %{answer}" + voted: "Has votado %{answer}" + banner: + featured_title: "#PróximaVotación" + info: "Nuevas propuestas ciudadanas han llegado a la fase de votación." proposal_notifications: new: title: "Enviar mensaje" @@ -397,6 +420,12 @@ es: show: back: "Volver a mi actividad" shared: + edit: 'Editar' + save: 'Guardar' + delete: 'Borrar' + comments: + title: 'Comentarios' + login_to_comment: 'Necesitas %{signin} o %{signup} para comentar.' advanced_search: author_type: 'Por categoría de autor' author_type_blank: 'Elige una categoría' diff --git a/config/locales/responders.en.yml b/config/locales/responders.en.yml index 68d77b0d2..ffe883d6c 100755 --- a/config/locales/responders.en.yml +++ b/config/locales/responders.en.yml @@ -21,4 +21,5 @@ en: proposal: "Proposal updated successfully." spending_proposal: "Investment project updated succesfully." destroy: - spending_proposal: "Spending proposal deleted succesfully." \ No newline at end of file + spending_proposal: "Spending proposal deleted succesfully." + error: "Could not delete" \ No newline at end of file diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml index 54c4c7035..4c9087557 100644 --- a/config/locales/responders.es.yml +++ b/config/locales/responders.es.yml @@ -21,4 +21,5 @@ es: poll_booth: "Urna actualizada correctamente." spending_proposal: "Propuesta de inversión actualizada correctamente." destroy: - spending_proposal: "Propuesta de inversión eliminada." \ No newline at end of file + spending_proposal: "Propuesta de inversión eliminada." + error: "No se pudo borrar" \ No newline at end of file diff --git a/config/locales/settings.en.yml b/config/locales/settings.en.yml index 0de4e5feb..8d4c55b5e 100755 --- a/config/locales/settings.en.yml +++ b/config/locales/settings.en.yml @@ -27,6 +27,8 @@ en: facebook_login: Facebook login google_login: Google login debates: Debates + polls: Polls spending_proposals: Investment projects spending_proposal_features: voting_allowed: Voting on investment projects + diff --git a/config/locales/settings.es.yml b/config/locales/settings.es.yml index 05ba6c076..e6736e982 100644 --- a/config/locales/settings.es.yml +++ b/config/locales/settings.es.yml @@ -27,6 +27,7 @@ es: facebook_login: Registro con Facebook google_login: Registro con Google debates: Debates + polls: Votaciones spending_proposals: Propuestas de inversión spending_proposal_features: voting_allowed: Votaciones sobre propuestas de inversión. \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 0d227717b..2b0965314 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -84,7 +84,7 @@ Rails.application.routes.draw do end resources :polls, only: [:show, :index] do - resources :questions, only: [:show], controller: 'polls/questions' do + resources :questions, only: [:show], controller: 'polls/questions', shallow: true do post :answer, on: :member end end @@ -190,6 +190,7 @@ Rails.application.routes.draw do resources :polls do resources :booths end + resources :questions, except: :show end resources :verifications, controller: :verifications, only: :index do diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 2c2f106ee..8b4693ea0 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -25,6 +25,7 @@ Setting.create(key: 'url', value: 'http://localhost:3000') Setting.create(key: 'org_name', value: 'Consul') Setting.create(key: 'place_name', value: 'City') Setting.create(key: 'feature.debates', value: "true") +Setting.create(key: 'feature.polls', value: "true") Setting.create(key: 'feature.spending_proposals', value: "true") Setting.create(key: 'feature.spending_proposal_features.voting_allowed', value: "true") Setting.create(key: 'feature.twitter_login', value: "true") From 198b0018f7e334a4c19432864b96b459a2974c55 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 17 Nov 2016 10:45:37 +0100 Subject: [PATCH 115/523] adds admin poll question's show --- .../admin/poll/questions_controller.rb | 8 ++-- app/views/admin/poll/questions/show.html.erb | 37 +++++++++++++++++++ config/locales/admin.en.yml | 7 ++++ config/locales/admin.es.yml | 7 ++++ config/routes.rb | 2 +- 5 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 app/views/admin/poll/questions/show.html.erb diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index 25b14251c..970d91b55 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -17,19 +17,21 @@ class Admin::Poll::QuestionsController < Admin::BaseController @question.author = @question.proposal.try(:author) || current_user if @question.save - redirect_to question_path(@question) + redirect_to admin_question_path(@question) else render :new end end - def edit + def show + end + def edit end def update if @question.update(question_params) - redirect_to question_path(@question), notice: t("flash.actions.save_changes.notice") + redirect_to admin_question_path(@question), notice: t("flash.actions.save_changes.notice") else render :edit end diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb new file mode 100644 index 000000000..942658f28 --- /dev/null +++ b/app/views/admin/poll/questions/show.html.erb @@ -0,0 +1,37 @@ +<% if @question.proposal.present? %> +
    + <%= I18n.t("admin.questions.show.proposal") %>: + <%= @question.proposal.title %> +
    +<% end %> + +
    +
    + <%= I18n.t("admin.questions.show.title") %>: + <%= @question.title %> +
    + +
    + <%= I18n.t("admin.questions.show.valid_answers") %>: + <%= @question.valid_answers.join(", ") %> +
    + +
    + <%= I18n.t("admin.questions.show.summary") %>: + <%= @question.summary %> +
    + +
    + <%= I18n.t("admin.questions.show.description") %>: + <%= @question.description %> +
    + +
    + <%= I18n.t("admin.questions.show.geozones") %>: + <% @question.geozones.each do |geozone| %> +
    + <% geozone.name %> +
    + <% end %> +
    +
    \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index c86f57266..e7e30e140 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -185,6 +185,13 @@ en: title: "Edit Question" new: title: "Create Question" + show: + proposal: Proposal + title: Title + valid_answers: Valid answers + summary: Summary + description: Description + geozones: Geozones booths: index: title: "List of booths" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index b579bfec5..22086889e 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -185,6 +185,13 @@ es: title: "Editar pregunta ciudadana" new: title: "Crear pregunta ciudadana" + show: + proposal: Propuesta Ciudadana + title: Título + valid_answers: Respuestas válidas + summary: Resumen + description: Descripción + geozones: Distritos booths: index: title: "Lista de urnas" diff --git a/config/routes.rb b/config/routes.rb index 2b0965314..ceecf3d88 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -190,7 +190,7 @@ Rails.application.routes.draw do resources :polls do resources :booths end - resources :questions, except: :show + resources :questions end resources :verifications, controller: :verifications, only: :index do From 9b46a7fe8f15c192e108db7b367e6b37093f0e1b Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 17 Nov 2016 11:52:51 +0100 Subject: [PATCH 116/523] tmp commit adds specs for admin poll questions --- spec/features/admin/poll/questions_spec.rb | 108 +++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 spec/features/admin/poll/questions_spec.rb diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb new file mode 100644 index 000000000..bab4e1a0e --- /dev/null +++ b/spec/features/admin/poll/questions_spec.rb @@ -0,0 +1,108 @@ +require 'rails_helper' + +feature 'Admin enquiries' do + background { login_as(create(:administrator).user) } + + scenario 'Index' do + e1 = create(:enquiry) + e2 = create(:enquiry) + + visit admin_enquiries_path + + expect(page).to have_content(e1.title) + expect(page).to have_content(e2.title) + end + + scenario 'Destroy' do + e1 = create(:enquiry) + e2 = create(:enquiry) + + visit admin_enquiries_path + + within("#enquiry_#{e1.id}") do + click_link "Delete" + end + + expect(page).to_not have_content(e1.title) + expect(page).to have_content(e2.title) + end + + scenario 'Update' do + e1 = create(:enquiry) + visit admin_enquiries_path + within("#enquiry_#{e1.id}") do + click_link "Edit" + end + + old_title = e1.title + new_title = "Potatoes are great and everyone should have one" + fill_in 'enquiry_title', with: new_title + + click_button 'Save' + + expect(page).to have_content "Changes saved" + expect(page).to have_content new_title + + visit admin_enquiries_path + + expect(page).to have_content(new_title) + expect(page).to_not have_content(old_title) + end + + scenario 'Create' do + title = "Star Wars: Episode IV - A New Hope" + summary = "It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire" + description = %{ + During the battle, Rebel spies managed to steal secret plans to the Empire's ultimate weapon, the DEATH STAR, an armored space station with enough power to destroy an entire planet. + Pursued by the Empire's sinister agents, Princess Leia races home aboard her starship, custodian of the stolen plans that can save her people and restore freedom to the galaxy.... + } + question = "Aren't you a little short for a stormtrooper?" + + visit admin_enquiries_path + click_link "Create enquiry" + + fill_in 'enquiry_title', with: title + fill_in 'enquiry_summary', with: summary + fill_in 'enquiry_description', with: description + fill_in 'enquiry_question', with: question + + click_button 'Save' + + expect(page).to have_content(title) + expect(page).to have_content(description) + expect(page).to have_content(summary) + expect(page).to have_content(question) + end + + scenario 'Create from successful proposal' do + geozones = create_list(:geozone, 3) + p = create(:proposal, :successful) + + visit proposals_path + click_link "Create enquiry" + + expect(current_path).to eq(new_admin_enquiry_path) + expect(page).to have_field('enquiry_title', with: p.title) + expect(page).to have_field('enquiry_summary', with: p.summary) + expect(page).to have_field('enquiry_description', with: p.description) + expect(page).to have_field('enquiry_question', with: p.question) + expect(page).to have_field('enquiry_valid_answers', with: "Yes, No") + + geozones.each do |g| + expect(page).to have_checked_field("enquiry_geozone_ids_#{g.id}") + end + + click_button 'Save' + + expect(page).to have_content(p.title) + expect(page).to have_content(p.summary) + expect(page).to have_content(p.description) + expect(page).to have_content(p.question) + expect(page).to have_link('Original proposal', href: proposal_path(p)) + expect(page).to have_link(p.author.name, href: user_path(p.author)) + geozones.each do |g| + expect(page).to have_content(g.name) + end + end + +end \ No newline at end of file From db94e241fea4c4329f4a773eb7ce1a874e1be824 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 17 Nov 2016 16:45:24 +0100 Subject: [PATCH 117/523] updates poll question path --- app/views/polls/show.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index d9bfbbd3b..7cfd02f99 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -27,7 +27,7 @@ <% @answerable_questions.each do |question| %>
    - <%= link_to question.title, poll_question_path(@poll, question) %> + <%= link_to question.title, question_path(question) %>
    <%= render 'polls/questions/answers', question: question %> @@ -44,7 +44,7 @@ <% @non_answerable_questions.each do |question| %>
    - <%= link_to question.title, poll_question_path(@poll, question) %> + <%= link_to question.title, question_path(question) %>
    <%= render 'polls/questions/answers', question: question %> From 626a8e9154269d75db2aefb04c6c4d592531ce33 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 17 Nov 2016 21:31:51 +0100 Subject: [PATCH 118/523] updates specs for admin poll questions --- app/models/poll/question.rb | 2 - app/views/admin/poll/questions/show.html.erb | 21 ++- app/views/proposals/_proposal.html.erb | 9 +- .../_proposal_ballots_banner.html.erb | 2 +- config/locales/admin.en.yml | 3 +- config/locales/admin.es.yml | 3 +- config/locales/en.yml | 2 +- config/locales/es.yml | 4 +- spec/factories.rb | 23 +-- spec/features/admin/poll/questions_spec.rb | 144 +++++++++--------- 10 files changed, 118 insertions(+), 95 deletions(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index c536fe5a3..350f19eae 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -14,13 +14,11 @@ class Poll::Question < ActiveRecord::Base belongs_to :proposal validates :title, presence: true - validates :question, presence: true validates :summary, presence: true validates :author, presence: true validates :title, length: { in: 4..Poll::Question.title_max_length } validates :description, length: { maximum: Poll::Question.description_max_length } - validates :question, length: { in: 10..Poll::Question.question_max_length } scope :sort_for_list, -> { order('poll_questions.proposal_id IS NULL', :created_at)} scope :for_render, -> { includes(:author, :proposal) } diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index 942658f28..5d1a0d01c 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -1,16 +1,21 @@ -<% if @question.proposal.present? %> -
    - <%= I18n.t("admin.questions.show.proposal") %>: - <%= @question.proposal.title %> -
    -<% end %> -
    + <% if @question.proposal.present? %> +
    + <%= I18n.t("admin.questions.show.proposal") %>: + <%= link_to @question.proposal.title, proposal_path(@question.proposal) %> +
    + <% end %> +
    <%= I18n.t("admin.questions.show.title") %>: <%= @question.title %>
    +
    + <%= I18n.t("admin.questions.show.author") %>: + <%= link_to @question.author.name, user_path(@question.author) %> +
    +
    <%= I18n.t("admin.questions.show.valid_answers") %>: <%= @question.valid_answers.join(", ") %> @@ -30,7 +35,7 @@ <%= I18n.t("admin.questions.show.geozones") %>: <% @question.geozones.each do |geozone| %>
    - <% geozone.name %> + <%= geozone.name %>
    <% end %>
    diff --git a/app/views/proposals/_proposal.html.erb b/app/views/proposals/_proposal.html.erb index 2c7bb272a..e786d7896 100644 --- a/app/views/proposals/_proposal.html.erb +++ b/app/views/proposals/_proposal.html.erb @@ -57,9 +57,16 @@

    <%= t("proposal_ballots.successfull", - voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %> + voting: link_to(t("proposal_ballots.voting"), polls_path)).html_safe %>

    + <% if can? :create, Poll::Question %> +

    + <%= link_to t('poll_questions.create_question'), + new_admin_question_path(proposal_id: proposal.id), + class: "button hollow" %> +

    + <% end %> <% elsif proposal.archived? %>
    <%= t("proposals.proposal.supports", count: proposal.total_votes) %> diff --git a/app/views/proposals/_proposal_ballots_banner.html.erb b/app/views/proposals/_proposal_ballots_banner.html.erb index df210a535..1e095b767 100644 --- a/app/views/proposals/_proposal_ballots_banner.html.erb +++ b/app/views/proposals/_proposal_ballots_banner.html.erb @@ -1,5 +1,5 @@
  • - +
    diff --git a/app/views/layouts/_admin_header.html.erb b/app/views/layouts/_admin_header.html.erb index d8dfe9d23..5fa3bc58f 100644 --- a/app/views/layouts/_admin_header.html.erb +++ b/app/views/layouts/_admin_header.html.erb @@ -1,11 +1,11 @@
    - +
    @@ -19,11 +19,13 @@
    - <%= link_to admin_root_path, class: "hide-for-small-only" do %> - <%= image_tag('logo_header.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> - <%= setting['org_name'] %> -  | <%= t("admin.dashboard.index.title") %> - <% end %> +

    + <%= link_to admin_root_path, class: "hide-for-small-only" do %> + <%= image_tag('logo_header.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> + <%= setting['org_name'] %> +  | <%= t("admin.dashboard.index.title") %> + <% end %> +

    diff --git a/app/views/layouts/admin.html.erb b/app/views/layouts/admin.html.erb index e5741086a..198bf3adf 100644 --- a/app/views/layouts/admin.html.erb +++ b/app/views/layouts/admin.html.erb @@ -30,7 +30,7 @@
    <%= render 'layouts/admin_header' %> -
    +
    @@ -46,7 +46,7 @@ <%= render 'layouts/flash' %> <%= yield %>
    -
    +
    From 6498d1c34dc1fd1ff16844ace5aedd46b9689969 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 14 Dec 2016 13:52:18 +0100 Subject: [PATCH 173/523] improves styles for admin polls views --- app/assets/stylesheets/admin.scss | 5 ++ app/views/admin/poll/polls/_booths.html.erb | 69 +++++++++---------- .../admin/poll/polls/_filter_subnav.html.erb | 50 ++++++-------- app/views/admin/poll/polls/_officers.html.erb | 57 +++++++-------- .../admin/poll/polls/_questions.html.erb | 49 ++++++------- 5 files changed, 105 insertions(+), 125 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index cc11557c5..5c7aab0fc 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -155,6 +155,11 @@ body.admin { } } +.admin .tabs-panel { + padding-left: 0; + padding-right: 0; +} + // 02. Sidebar // ----------- diff --git a/app/views/admin/poll/polls/_booths.html.erb b/app/views/admin/poll/polls/_booths.html.erb index ae6d28abe..4d52d8a74 100644 --- a/app/views/admin/poll/polls/_booths.html.erb +++ b/app/views/admin/poll/polls/_booths.html.erb @@ -1,39 +1,34 @@ -
    -
    - <% if @poll.booths.empty? %> -
    - <%= t("admin.polls.show.no_booths") %> -
    - <% else %> +

    <%= t("admin.polls.show.booths_title") %>

    -

    <%= t("admin.polls.show.booths_title") %>

    - - - - - - - - - <% @poll.booths.each do |booth| %> - - - - - - <% end %> - -
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> 
    - - <%= link_to booth.name, admin_booth_path(booth) %> - - - <%= booth.location %> - - <%= link_to t("admin.polls.show.remove_booth"), - "#", - class: "button hollow alert" %> -
    - <% end %> +<% if @poll.booths.empty? %> +
    + <%= t("admin.polls.show.no_booths") %>
    -
    \ No newline at end of file +<% else %> + + + + + + + + <% @poll.booths.each do |booth| %> + + + + + + <% end %> + +
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> 
    + + <%= link_to booth.name, admin_booth_path(booth) %> + + + <%= booth.location %> + + <%= link_to t("admin.polls.show.remove_booth"), + "#", + class: "button hollow alert" %> +
    +<% end %> diff --git a/app/views/admin/poll/polls/_filter_subnav.html.erb b/app/views/admin/poll/polls/_filter_subnav.html.erb index d92cf7235..e55e52f63 100644 --- a/app/views/admin/poll/polls/_filter_subnav.html.erb +++ b/app/views/admin/poll/polls/_filter_subnav.html.erb @@ -1,30 +1,20 @@ -
    -
    -
      -
    • - <%= link_to "#tab-questions" do %> -

      - <%= t("admin.polls.show.questions_tab") %> - (<%= @poll.questions.count %>) -

      - <% end %> -
    • -
    • - <%= link_to "#tab-booths" do %> -

      - <%= t("admin.polls.show.booths_tab") %> - (<%= @poll.booths.count %>) -

      - <% end %> -
    • -
    • - <%= link_to "#tab-officers" do %> -

      - <%= t("admin.polls.show.officers_tab") %> - (<%= @poll.officers.count %>) -

      - <% end %> -
    • -
    -
    -
    \ No newline at end of file +
      +
    • + <%= link_to "#tab-questions" do %> + <%= t("admin.polls.show.questions_tab") %> + (<%= @poll.questions.count %>) + <% end %> +
    • +
    • + <%= link_to "#tab-booths" do %> + <%= t("admin.polls.show.booths_tab") %> + (<%= @poll.booths.count %>) + <% end %> +
    • +
    • + <%= link_to "#tab-officers" do %> + <%= t("admin.polls.show.officers_tab") %> + (<%= @poll.officers.count %>) + <% end %> +
    • +
    diff --git a/app/views/admin/poll/polls/_officers.html.erb b/app/views/admin/poll/polls/_officers.html.erb index 240eb7b1c..11b4cce50 100644 --- a/app/views/admin/poll/polls/_officers.html.erb +++ b/app/views/admin/poll/polls/_officers.html.erb @@ -1,33 +1,28 @@ -
    -
    - <% if @poll.officers.empty? %> -
    - <%= t("admin.polls.show.no_officers") %> -
    - <% else %> +

    <%= t("admin.polls.show.officers_title") %>

    -

    <%= t("admin.polls.show.officers_title") %>

    - - - - - - - - <% @poll.officers.each do |officer| %> - - - - - <% end %> - -
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.email") %>
    - - <%= officer.name %> - - - <%= officer.email %> -
    - <% end %> +<% if @poll.officers.empty? %> +
    + <%= t("admin.polls.show.no_officers") %>
    -
    \ No newline at end of file +<% else %> + + + + + + + <% @poll.officers.each do |officer| %> + + + + + <% end %> + +
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.email") %>
    + + <%= officer.name %> + + + <%= officer.email %> +
    +<% end %> diff --git a/app/views/admin/poll/polls/_questions.html.erb b/app/views/admin/poll/polls/_questions.html.erb index 91f33196c..08b094ddf 100644 --- a/app/views/admin/poll/polls/_questions.html.erb +++ b/app/views/admin/poll/polls/_questions.html.erb @@ -1,29 +1,24 @@ -
    -
    - <% if @poll.questions.empty? %> -
    - <%= t('admin.polls.show.no_questions') %> -
    - <% else %> +

    <%= t("admin.polls.show.questions_title") %>

    -

    <%= t("admin.polls.show.questions_title") %>

    - - - <% @poll.questions.each do |question| %> - - - - - <% end %> -
    <%= link_to question.title, admin_question_path(question) %> - <%= link_to t('shared.edit'), - edit_admin_question_path(question), - class: "button hollow" %> - <%= link_to t('shared.delete'), - admin_question_path(question), - class: "button hollow alert", - method: :delete %> -
    - <% end %> +<% if @poll.questions.empty? %> +
    + <%= t('admin.polls.show.no_questions') %>
    -
    \ No newline at end of file +<% else %> + + <% @poll.questions.each do |question| %> + + + + + <% end %> +
    <%= link_to question.title, admin_question_path(question) %> + <%= link_to t('shared.edit'), + edit_admin_question_path(question), + class: "button hollow" %> + <%= link_to t('shared.delete'), + admin_question_path(question), + class: "button hollow alert", + method: :delete %> +
    +<% end %> From cbbc3ed1bef50c08dddb284cf28a16705de1ef3b Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 14 Dec 2016 17:58:21 +0100 Subject: [PATCH 174/523] improves styles for admin questions views --- app/assets/stylesheets/admin.scss | 13 ++++++++++--- app/views/admin/poll/questions/_filter.html.erb | 15 +++++++-------- app/views/admin/poll/questions/_form.html.erb | 14 +++++++++----- app/views/admin/poll/questions/_search.html.erb | 14 ++++++-------- app/views/admin/poll/questions/index.html.erb | 13 ++++++++++--- config/locales/admin.en.yml | 3 +++ config/locales/admin.es.yml | 5 ++++- 7 files changed, 49 insertions(+), 28 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 5c7aab0fc..adc166d96 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -84,6 +84,11 @@ body.admin { color: $admin-color; } + .tabs-panel { + padding-left: 0; + padding-right: 0; + } + #proposals { width: 100% !important; } @@ -155,9 +160,11 @@ body.admin { } } -.admin .tabs-panel { - padding-left: 0; - padding-right: 0; +.input-group { + + .input-group-button { + padding-bottom: rem-calc(16); + } } // 02. Sidebar diff --git a/app/views/admin/poll/questions/_filter.html.erb b/app/views/admin/poll/questions/_filter.html.erb index c12c62f2d..0fd800067 100644 --- a/app/views/admin/poll/questions/_filter.html.erb +++ b/app/views/admin/poll/questions/_filter.html.erb @@ -1,8 +1,7 @@ -
    - <%= form_tag '', method: :get do %> - <%= select_tag "poll_id", - poll_select_options(true), - prompt: t("admin.questions.index.select_poll"), - class: "js-location-changer" %> - <% end %> -
    \ No newline at end of file +<%= form_tag '', method: :get do %> + <%= label_tag :poll_id, t("admin.questions.index.filter_poll") %> + <%= select_tag "poll_id", + poll_select_options(true), + prompt: t("admin.questions.index.select_poll"), + class: "js-location-changer" %> +<% end %> diff --git a/app/views/admin/poll/questions/_form.html.erb b/app/views/admin/poll/questions/_form.html.erb index f9362995b..dbc8883e3 100644 --- a/app/views/admin/poll/questions/_form.html.erb +++ b/app/views/admin/poll/questions/_form.html.erb @@ -7,15 +7,19 @@
    -
    - <%= f.select :poll_id, - options_for_select(Poll.pluck(:name, :id)), - prompt: t("admin.questions.index.select_poll") %> +
    + <%= f.select :poll_id, + options_for_select(Poll.pluck(:name, :id)), + prompt: t("admin.questions.index.select_poll"), + label: t("admin.questions.new.poll_label") %>
    <%= f.text_field :title, maxlength: Poll::Question.title_max_length %> - <%= f.text_field :valid_answers %> + <%= f.label :valid_answers %> +

    <%= t("admin.questions.new.valid_answers_note") %>

    + <%= f.text_field :valid_answers, label: false %> + <%= f.text_area :summary, rows: 4, maxlength: 200 %> diff --git a/app/views/admin/poll/questions/_search.html.erb b/app/views/admin/poll/questions/_search.html.erb index 30cf0d6e5..7ee1308f7 100644 --- a/app/views/admin/poll/questions/_search.html.erb +++ b/app/views/admin/poll/questions/_search.html.erb @@ -1,12 +1,10 @@ <%= form_tag(admin_questions_path, method: :get) do |f| %> -
    -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.spending_proposal_search.placeholder") %> -
    -
    +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.spending_proposal_search.placeholder") %> +
    <%= submit_tag t("admin.shared.spending_proposal_search.button"), class: "button" %>
    -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/admin/poll/questions/index.html.erb b/app/views/admin/poll/questions/index.html.erb index 2aef2b6e5..77772fbf7 100644 --- a/app/views/admin/poll/questions/index.html.erb +++ b/app/views/admin/poll/questions/index.html.erb @@ -3,11 +3,18 @@ <%= link_to t('admin.questions.index.create'), new_admin_question_path, class: "button success float-right" %> -<%= render 'filter' %> -<%= render 'search' %> +
    +
    + <%= render 'search' %> +
    +
    + +
    + <%= render 'filter' %> +
    <% if @questions.count == 0 %> -
    +
    <%= t('admin.questions.index.no_questions') %>
    <% else %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 4c498a280..09f5e16fb 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -194,11 +194,14 @@ en: title: "Questions" create: "Create question" no_questions: "There are no questions." + filter_poll: Filter by Poll select_poll: Select Poll edit: title: "Edit Question" new: title: "Create Question" + poll_label: "Poll" + valid_answers_note: "Enter the answers separated by commas (,)" show: proposal: Original proposal author: Author diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 2e294147a..f96d2d815 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -194,11 +194,14 @@ es: title: "Preguntas ciudadanas" create: "Crear pregunta ciudadana" no_questions: "No hay ninguna pregunta ciudadana." - select_poll: Seleccionar votación + filter_poll: "Filtrar por votación" + select_poll: "Seleccionar votación" edit: title: "Editar pregunta ciudadana" new: title: "Crear pregunta ciudadana" + poll_label: "Votación" + valid_answers_note: "Escribe las respuestas separadas por comas (,)" show: proposal: Propuesta ciudadana original author: Autor From b290a776dd20f4b8df66d961201e7ad337da0eda Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 14 Dec 2016 18:13:33 +0100 Subject: [PATCH 175/523] improves styles for admin officers views --- .../admin/poll/officers/_officer.html.erb | 56 ++++++++++--------- .../admin/poll/officers/_search.html.erb | 9 +++ app/views/admin/poll/officers/index.html.erb | 25 +++++---- config/locales/admin.en.yml | 3 + config/locales/admin.es.yml | 3 + 5 files changed, 60 insertions(+), 36 deletions(-) create mode 100644 app/views/admin/poll/officers/_search.html.erb diff --git a/app/views/admin/poll/officers/_officer.html.erb b/app/views/admin/poll/officers/_officer.html.erb index c9251548d..80434f385 100644 --- a/app/views/admin/poll/officers/_officer.html.erb +++ b/app/views/admin/poll/officers/_officer.html.erb @@ -1,26 +1,30 @@ -
    - - - - - - - - -
    - <%= officer.name %> - - <%= officer.email %> - - <% if officer.persisted? %> - <%= link_to t('admin.poll_officers.officer.delete'), - admin_poll_officer_path(officer), - method: :delete, - class: "button hollow alert" %> - <% else %> - <%= link_to t('admin.poll_officers.officer.add'),{ controller: "admin/poll/officers", action: :create, user_id: officer.user_id }, - method: :post, - class: "button success" %> - <% end %> -
    -
    + + + + + + + + + + + + + + +
    <%= t('admin.poll_officers.officer.name') %><%= t('admin.poll_officers.officer.email') %>
    + <%= officer.name %> + + <%= officer.email %> + + <% if officer.persisted? %> + <%= link_to t('admin.poll_officers.officer.delete'), + admin_poll_officer_path(officer), + method: :delete, + class: "button hollow alert" %> + <% else %> + <%= link_to t('admin.poll_officers.officer.add'),{ controller: "admin/poll/officers", action: :create, user_id: officer.user_id }, + method: :post, + class: "button success" %> + <% end %> +
    diff --git a/app/views/admin/poll/officers/_search.html.erb b/app/views/admin/poll/officers/_search.html.erb new file mode 100644 index 000000000..dda22dee2 --- /dev/null +++ b/app/views/admin/poll/officers/_search.html.erb @@ -0,0 +1,9 @@ +<%= form_tag search_admin_officers_path, method: :get, remote: true do %> +
    + <%= text_field_tag :email, '', + placeholder: t("admin.poll_officers.search.email_placeholder") %> +
    + <%= submit_tag t("admin.poll_officers.search.search"), class: "button" %> +
    +
    +<% end %> diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index cc6393204..d6e11682b 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -1,21 +1,25 @@

    <%= t("admin.poll_officers.index.title") %>

    - <%= form_tag search_admin_officers_path, method: :get, remote: true do %> -
    - <%= text_field_tag :email, '', placeholder: t('admin.poll_officers.search.email_placeholder') %> -
    -
    - <%= submit_tag t('admin.poll_officers.search.search'), class: 'button' %> -
    - <% end %> +
    + <%= render 'search' %> +
    -
    +
    -

    <%= page_entries_info @officers %>

    +

    + <%= page_entries_info @officers, entry_name: t('admin.poll_officers.officer.entry_name') %> +

    + + + + + + + <% @officers.each do |officer| %> <% end %> +
    <%= t('admin.poll_officers.officer.name') %><%= t('admin.poll_officers.officer.email') %>
    @@ -41,6 +45,7 @@
    <%= paginate @officers %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 09f5e16fb..fa5fb528f 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -154,6 +154,9 @@ en: officer: add: Add delete: Delete + name: Name + email: Email + entry_name: officer search: email_placeholder: Search user by email search: Search diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index f96d2d815..11cfe8d2a 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -154,6 +154,9 @@ es: officer: add: Añadir como Presidente de mesa delete: Borrar + name: Nombre + email: Email + entry_name: presidente de mesa search: email_placeholder: Buscar usuario por email search: Buscar From d5f9bb1d11302ebb10c1864919bdfabe1bc7e074 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 14 Dec 2016 18:37:38 +0100 Subject: [PATCH 176/523] improves styles for admin booths views --- app/views/admin/poll/booths/index.html.erb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/booths/index.html.erb b/app/views/admin/poll/booths/index.html.erb index d61c67ed1..9618aec59 100644 --- a/app/views/admin/poll/booths/index.html.erb +++ b/app/views/admin/poll/booths/index.html.erb @@ -1,4 +1,7 @@ -

    <%= t("admin.booths.index.title") %>

    +

    <%= t("admin.booths.index.title") %>

    + +<%= link_to t("admin.booths.index.add_booth"), new_admin_booth_path, + class: "button success float-right" %> <% if @booths.empty? %>
    @@ -6,10 +9,6 @@
    <% end %> -<%= link_to t("admin.booths.index.add_booth"), - new_admin_booth_path, - class: "button success" %> - <% if @booths.any? %>

    <%= page_entries_info @booths %>

    From 0ddf7a003c1c7545d7cde0a5f3f19898c868d503 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 14:02:03 +0100 Subject: [PATCH 177/523] adds dates on polls index --- app/views/admin/poll/polls/_poll.html.erb | 3 +-- app/views/admin/poll/polls/index.html.erb | 2 +- config/locales/admin.en.yml | 2 +- config/locales/admin.es.yml | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/polls/_poll.html.erb b/app/views/admin/poll/polls/_poll.html.erb index 4128ad222..e02a80a7a 100644 --- a/app/views/admin/poll/polls/_poll.html.erb +++ b/app/views/admin/poll/polls/_poll.html.erb @@ -5,8 +5,7 @@ <% end %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index a3dddb17f..1210affa7 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -161,6 +161,22 @@ en: email_placeholder: Search user by email search: Search user_not_found: User not found + poll_officer_assignments: + flash: + destroy: "Officing shift removed" + create: "Officing shift added" + error_destroy: "An error ocurred when removing officer assignment" + error_create: "An error ocurred when adding officer assignment" + index: + new_assignment: "New shift" + date: "Date" + booth: "Booth" + select_date: "Select day" + select_booth: "Select booth" + add_assignment: "Add shift" + remove_assignment: "Remove" + assignments: "Officing shifts in this poll" + no_assignments: "This user has no officing shifts in this poll" polls: index: title: "List of polls" @@ -192,6 +208,8 @@ en: remove_question: "Remove question from poll" add_booth: "Assign booth" add_question: "Include question" + add_officer_assignments: "Add shifts as officer" + edit_officer_assignments: "Edit officing shifts" name: "Name" location: "Location" email: "Email" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 03ceb208e..1f2ea2257 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -161,6 +161,22 @@ es: email_placeholder: Buscar usuario por email search: Buscar user_not_found: Usuario no encontrado + poll_officer_assignments: + flash: + destroy: "Eliminado turno de presidente de mesa" + create: "Añadido turno de presidente de mesa" + error_destroy: "Se ha producido un error al eliminar el turno" + error_create: "Se ha producido un error al intentar crear el turno" + index: + new_assignment: "Nuevo turno" + date: "Fecha" + booth: "Urna" + select_date: "Seleccionar día" + select_booth: "Seleccionar urna" + add_assignment: "Añadir turno" + remove_assignment: "Eliminar turno" + assignments: "Turnos como presidente de mesa en esta votación" + no_assignments: "No tiene turnos como presidente de mesa en esta votación" polls: index: title: "Listado de votaciones" @@ -192,6 +208,8 @@ es: remove_question: "Desasignar pregunta" add_booth: "Asignar urna" add_question: "Incluir pregunta" + add_officer_assignments: "Añadir turnos como presidente de mesa" + edit_officer_assignments: "Editar turnos" name: "Nombre" location: "Ubicación" email: "Email" diff --git a/config/routes.rb b/config/routes.rb index 63b0e9f6e..96e2db196 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -197,7 +197,7 @@ Rails.application.routes.draw do resources :booths resources :booth_assignments, only: [:create, :destroy] - resources :officer_assignments, only: [:new, :create, :destroy] + resources :officer_assignments, only: [:index, :create, :destroy] resources :questions end diff --git a/spec/features/admin/poll/officer_assignments_spec.rb b/spec/features/admin/poll/officer_assignments_spec.rb new file mode 100644 index 000000000..3cbf9fb13 --- /dev/null +++ b/spec/features/admin/poll/officer_assignments_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +feature 'Admin officer assignments in poll' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario 'Assign officer to poll', :js do + booth_assignment = create(:poll_booth_assignment) + officer = create(:poll_officer) + + visit admin_poll_path(booth_assignment.poll) + within('#poll-resources') do + click_link 'Officers (0)' + end + + expect(page).to have_content 'There are no officers assigned to this poll' + + fill_in 'search-officers', with: officer.name + click_button 'Search' + + within('#search-officers-results') do + click_link 'Add shifts as officer' + end + + expect(page).to have_content 'This user has no officing shifts in this poll' + expect(page).to have_content officer.name + expect(page).to have_content booth_assignment.poll.name + + within('#officer_assignment_form') do + select I18n.l(booth_assignment.poll.ends_at.to_date), from: 'date' + select "#{booth_assignment.booth.name} (#{booth_assignment.booth.location})", from: 'booth_id' + click_button 'Add shift' + end + + expect(page).to have_content 'Officing shift added' + expect(page).to_not have_content 'This user has no officing shifts in this poll' + + visit admin_poll_path(booth_assignment.poll) + within('#poll-resources') do + click_link 'Officers (1)' + end + + expect(page).to_not have_content 'There are no officers in this poll' + expect(page).to have_content officer.name + expect(page).to have_content officer.email + end + + scenario 'remove booth from poll' do + officer_assignment = create(:poll_officer_assignment) + poll = officer_assignment.booth_assignment.poll + booth = officer_assignment.booth_assignment.booth + officer = officer_assignment.officer + + visit admin_officer_assignments_path(poll: poll, officer: officer) + + expect(page).to_not have_content 'This user has no officing shifts in this poll' + within("#poll_officer_assignment_#{officer_assignment.id}") do + expect(page).to have_content booth.name + click_link 'Remove' + end + + expect(page).to have_content 'Officing shift removed' + expect(page).to have_content 'This user has no officing shifts in this poll' + end +end \ No newline at end of file From 2aff1d71fe691b56dcf91ab9a7c84e0345dc4b09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 17:47:27 +0100 Subject: [PATCH 214/523] makes count uniq --- app/views/admin/poll/polls/_filter_subnav.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/polls/_filter_subnav.html.erb b/app/views/admin/poll/polls/_filter_subnav.html.erb index 751541beb..dc192be5f 100644 --- a/app/views/admin/poll/polls/_filter_subnav.html.erb +++ b/app/views/admin/poll/polls/_filter_subnav.html.erb @@ -14,7 +14,7 @@
  • <%= link_to "#tab-officers" do %> <%= t("admin.polls.show.officers_tab") %> - (<%= @poll.officers.count %>) + (<%= @poll.officers.uniq.count %>) <% end %>
  • From 3ad648dd63c2d6a9e26dd20104e66144b2317953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 17:47:54 +0100 Subject: [PATCH 215/523] display correct submenu in admin menu --- app/helpers/admin_helper.rb | 2 +- app/views/admin/_menu.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index ec99c240b..d0b0765dd 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -17,7 +17,7 @@ module AdminHelper end def menu_polls? - ["polls", "questions", "officers", "booths"].include? controller_name + ["polls", "questions", "officers", "booths", "officer_assignments"].include? controller_name end def menu_profiles? diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index b2f4eb5d8..078dad9b1 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -60,7 +60,7 @@ <%= t("admin.menu.title_polls") %>
      > -
    • > +
    • > <%= link_to t('admin.menu.polls'), admin_polls_path %>
    • From ab61d94d2df399bf55ab5fdc9cff875b1cc92c2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 18:26:03 +0100 Subject: [PATCH 216/523] changes Time.now to Time.current --- app/models/poll.rb | 12 ++++++------ app/models/signature.rb | 4 ++-- db/dev_seeds.rb | 4 ++-- spec/factories.rb | 2 +- spec/features/verification/residence_spec.rb | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 72901d9d4..47a955681 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -10,21 +10,21 @@ class Poll < ActiveRecord::Base validate :date_range - scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.now, Time.now) } - scope :incoming, -> { where('? < starts_at', Time.now) } - scope :expired, -> { where('ends_at < ?', Time.now) } + scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.current, Time.current) } + scope :incoming, -> { where('? < starts_at', Time.current) } + scope :expired, -> { where('ends_at < ?', Time.current) } scope :sort_for_list, -> { order(:starts_at) } - def current?(timestamp = DateTime.now) + def current?(timestamp = DateTime.current) starts_at <= timestamp && timestamp <= ends_at end - def incoming?(timestamp = DateTime.now) + def incoming?(timestamp = DateTime.current) timestamp < starts_at end - def expired?(timestamp = DateTime.now) + def expired?(timestamp = DateTime.current) ends_at < timestamp end diff --git a/app/models/signature.rb b/app/models/signature.rb index 47408858a..87e3d6b0c 100644 --- a/app/models/signature.rb +++ b/app/models/signature.rb @@ -49,8 +49,8 @@ class Signature < ActiveRecord::Base user_params = { document_number: document_number, created_from_signature: true, - verified_at: Time.now, - erased_at: Time.now, + verified_at: Time.current, + erased_at: Time.current, password: random_password, terms_of_service: '1', email: nil diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index ae48d3625..9bdffe36b 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -203,7 +203,7 @@ tags = Faker::Lorem.words(25) responsible_name: Faker::Name.name, external_url: Faker::Internet.url, description: description, - created_at: rand((Time.now - 1.week) .. Time.now), + created_at: rand((Time.current - 1.week) .. Time.current), tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1", @@ -461,7 +461,7 @@ puts "Commenting Poll Questions" author = User.reorder("RANDOM()").first question = Poll::Question.reorder("RANDOM()").first Comment.create!(user: author, - created_at: rand(question.created_at .. Time.now), + created_at: rand(question.created_at .. Time.current), commentable: question, body: Faker::Lorem.sentence) end \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb index 7323ee633..f529e4e84 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -310,7 +310,7 @@ FactoryGirl.define do factory :poll_officer_assignment, class: 'Poll::OfficerAssignment' do association :officer, factory: :poll_officer association :booth_assignment, factory: :poll_booth_assignment - date Time.now.to_date + date Time.current.to_date end factory :poll_voter, class: 'Poll::Voter' do diff --git a/spec/features/verification/residence_spec.rb b/spec/features/verification/residence_spec.rb index cdf33dfab..58d2c8092 100644 --- a/spec/features/verification/residence_spec.rb +++ b/spec/features/verification/residence_spec.rb @@ -104,7 +104,7 @@ feature 'Residence' do end scenario 'Error when trying to verify a deregistered account' do - create(:user, document_number: '12345678Z', document_type: '1', erased_at: Time.now) + create(:user, document_number: '12345678Z', document_type: '1', erased_at: Time.current) login_as(create(:user)) From 7b6713f8bb4700984bf82d978a703a0139e6076b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 18:26:27 +0100 Subject: [PATCH 217/523] fixes typo in method call --- app/controllers/debates_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb index 8262f014a..6d17eb749 100644 --- a/app/controllers/debates_controller.rb +++ b/app/controllers/debates_controller.rb @@ -22,7 +22,7 @@ class DebatesController < ApplicationController def index_customization @featured_debates = @debates.featured - @proposal_successfull_exists = Proposal.successfull.exists? + @proposal_successfull_exists = Proposal.successful.exists? end def show From b63d9ac98e724c3e5b0eb3ebaff961f3a1e055ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 18:36:46 +0100 Subject: [PATCH 218/523] removes unused key --- config/locales/admin.en.yml | 1 - config/locales/admin.es.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index ab545598a..d0343fd4f 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -97,7 +97,6 @@ en: banner: Manage banners poll_questions: Poll questions proposals_topics: Proposals topics - debate_topics: Debate topics geozones: Manage geozones hidden_comments: Hidden comments hidden_debates: Hidden debates diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 3aceb6fb2..f1b477e74 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -97,7 +97,6 @@ es: banner: Gestionar banners proposals_topics: Temas de propuestas poll_questions: Preguntas ciudadanas - debate_topics: Temas de debate geozones: Gestionar distritos hidden_comments: Comentarios ocultos hidden_debates: Debates ocultos From 3fc489652992a0c3c5f8f1dcb1c603f54b69d149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 18:37:04 +0100 Subject: [PATCH 219/523] adds unsettled geozones menu item to admin menu --- app/views/admin/_menu.html.erb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 52c66e0c3..09eede256 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -119,6 +119,12 @@
    +
  • > + <%= link_to admin_geozones_path do %> + <%= t('admin.menu.geozones') %> + <% end %> +
  • + <% if feature?(:signature_sheets) %>
  • > <%= link_to admin_signature_sheets_path do %> From 402d709930d68df81dcb8d6436127be018d3554a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 18:48:36 +0100 Subject: [PATCH 220/523] adds menu item to main bar for poll officers --- app/models/user.rb | 4 ++++ app/views/shared/_admin_login_items.html.erb | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 688fde1b1..59495dc1f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -114,6 +114,10 @@ class User < ActiveRecord::Base manager.present? end + def poll_officer? + poll_officer.present? + end + def organization? organization.present? end diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index cfe3cc1c9..078d02c01 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -23,9 +23,9 @@
  • <% end %> - <%# if current_user.administrator? || current_user.officer? %> + <% if current_user.administrator? || current_user.poll_officer? %>
  • <%= link_to t("layouts.header.officing"), officing_root_path %>
  • - <%# end %> + <% end %> <% end %> From 454ae678e6e5fb9b4e148d4865b05d78c463df22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 27 Dec 2016 18:51:38 +0100 Subject: [PATCH 221/523] adds spec for user#poll_officer? --- spec/models/user_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ed0bac164..0f03086ba 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -151,6 +151,18 @@ describe User do end end + describe "poll_officer?" do + it "is false when the user is not a poll officer" do + expect(subject.poll_officer?).to be false + end + + it "is true when the user is a poll officer" do + subject.save + create(:poll_officer, user: subject) + expect(subject.poll_officer?).to be true + end + end + describe "organization?" do it "is false when the user is not an organization" do expect(subject.organization?).to be false From a511480ce22b418f3ead2ce8d3a7e7be6ef78cab Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 12:41:04 +0100 Subject: [PATCH 222/523] improves styles for admin menu --- app/views/admin/_menu.html.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 09eede256..1b4911412 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -119,16 +119,16 @@ -
  • > +
  • > <%= link_to admin_geozones_path do %> - <%= t('admin.menu.geozones') %> + <%= t('admin.menu.geozones') %> <% end %>
  • <% if feature?(:signature_sheets) %> -
  • > +
  • > <%= link_to admin_signature_sheets_path do %> - <%= t("admin.menu.signature_sheets") %> + <%= t("admin.menu.signature_sheets") %> <% end %>
  • <% end %> From c2b6cda4066bc2c53048158335c8a0ad831f6df2 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 12:49:02 +0100 Subject: [PATCH 223/523] improves styles of search forms --- .../admin/poll/polls/_search_booths.html.erb | 12 +++++------- .../admin/poll/polls/_search_officers.html.erb | 12 +++++------- .../poll/polls/_search_questions.html.erb | 13 ++++++------- app/views/admin/poll/polls/show.html.erb | 18 +++++++++++++++--- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/app/views/admin/poll/polls/_search_booths.html.erb b/app/views/admin/poll/polls/_search_booths.html.erb index 56d9cbb12..e4b038e3a 100644 --- a/app/views/admin/poll/polls/_search_booths.html.erb +++ b/app/views/admin/poll/polls/_search_booths.html.erb @@ -1,11 +1,9 @@ <%= form_tag(search_booths_admin_poll_path(@poll), method: :get, remote: true) do |f| %> -
    -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.booths_search.placeholder"), id: "search-booths" %> -
    -
    +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.booths_search.placeholder"), id: "search-booths" %> +
    <%= submit_tag t("admin.shared.booths_search.button"), class: "button" %>
    diff --git a/app/views/admin/poll/polls/_search_officers.html.erb b/app/views/admin/poll/polls/_search_officers.html.erb index 45ce9bd8f..53d7c1105 100644 --- a/app/views/admin/poll/polls/_search_officers.html.erb +++ b/app/views/admin/poll/polls/_search_officers.html.erb @@ -1,11 +1,9 @@ <%= form_tag(search_officers_admin_poll_path(@poll), method: :get, remote: true) do |f| %> -
    -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.poll_officers_search.placeholder"), id: "search-officers" %> -
    -
    +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.poll_officers_search.placeholder"), id: "search-officers" %> +
    <%= submit_tag t("admin.shared.poll_officers_search.button"), class: "button" %>
    diff --git a/app/views/admin/poll/polls/_search_questions.html.erb b/app/views/admin/poll/polls/_search_questions.html.erb index 0a6123c1b..2f82d82cf 100644 --- a/app/views/admin/poll/polls/_search_questions.html.erb +++ b/app/views/admin/poll/polls/_search_questions.html.erb @@ -1,11 +1,10 @@ <%= form_tag(search_questions_admin_poll_path(@poll), method: :get, remote: true) do |f| %> -
    -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.poll_questions_search.placeholder"), id: "search-questions" %> -
    -
    +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.poll_questions_search.placeholder"), id: "search-questions" %> + +
    <%= submit_tag t("admin.shared.poll_questions_search.button"), class: "button" %>
    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index e357bc7f4..5a59cfa9e 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -11,17 +11,29 @@ <%= render "filter_subnav" %>
    - <%= render "search_questions" %> +
    +
    + <%= render "search_questions" %> +
    +
    <%= render "questions" %>
    - <%= render "search_booths" %> +
    +
    + <%= render "search_booths" %> +
    +
    <%= render "booths" %>
    - <%= render "search_officers" %> +
    +
    + <%= render "search_officers" %> +
    +
    <%= render 'officers' %>
    \ No newline at end of file From 8e3f80628d88549960c927e3a94c89e162572e9d Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 12:52:36 +0100 Subject: [PATCH 224/523] improves callout officer not found --- app/views/admin/poll/officers/user_not_found.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/officers/user_not_found.js.erb b/app/views/admin/poll/officers/user_not_found.js.erb index 40b6caac5..a6444dc61 100644 --- a/app/views/admin/poll/officers/user_not_found.js.erb +++ b/app/views/admin/poll/officers/user_not_found.js.erb @@ -1 +1 @@ -$("#search-result").html("
    <%= j t('admin.poll_officers.search.user_not_found') %>
    "); +$("#search-result").html("
    <%= j t('admin.poll_officers.search.user_not_found') %>
    "); From 69ab67a81f85dde62a2d784f53d2c26ee9f0acdb Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 12:53:04 +0100 Subject: [PATCH 225/523] hides table if there are no officers --- app/views/admin/poll/officers/index.html.erb | 74 ++++++++++---------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/app/views/admin/poll/officers/index.html.erb b/app/views/admin/poll/officers/index.html.erb index d6e11682b..fd9619167 100644 --- a/app/views/admin/poll/officers/index.html.erb +++ b/app/views/admin/poll/officers/index.html.erb @@ -12,40 +12,42 @@ <%= page_entries_info @officers, entry_name: t('admin.poll_officers.officer.entry_name') %> -
    - Próximamente -
    (15/12/2016 - 15/02/2017) + <%= l poll.starts_at.to_date %> - <%= l poll.ends_at.to_date %>
    <%= link_to t("admin.actions.edit"), diff --git a/app/views/admin/poll/polls/index.html.erb b/app/views/admin/poll/polls/index.html.erb index b4c18d21b..75b52affa 100644 --- a/app/views/admin/poll/polls/index.html.erb +++ b/app/views/admin/poll/polls/index.html.erb @@ -8,7 +8,7 @@ - + diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index fa5fb528f..a99f0d969 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -167,7 +167,7 @@ en: no_polls: "There are no polls." create: "Create poll" name: "Name" - status: "Status" + dates: "Dates" new: title: "New poll" submit_button: "Create poll" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 11cfe8d2a..d58fa4230 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -167,7 +167,7 @@ es: no_polls: "No hay ninguna votación." create: "Crear votación" name: "Nombre" - status: "Estado" + dates: "Fechas" new: title: "Nueva votación" submit_button: "Crear votación" From 30a56d21f7f03459e8c6077f15e9165fbb710ec7 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 14:09:04 +0100 Subject: [PATCH 178/523] changes text to remove questions on polls questions list --- app/views/admin/poll/polls/_questions.html.erb | 5 +---- config/locales/admin.en.yml | 1 + config/locales/admin.es.yml | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/views/admin/poll/polls/_questions.html.erb b/app/views/admin/poll/polls/_questions.html.erb index 08b094ddf..1cd8597bb 100644 --- a/app/views/admin/poll/polls/_questions.html.erb +++ b/app/views/admin/poll/polls/_questions.html.erb @@ -10,10 +10,7 @@
    <%= t("admin.polls.index.name") %><%= t("admin.polls.index.status") %><%= t("admin.polls.index.dates") %>  
    <%= link_to question.title, admin_question_path(question) %> - <%= link_to t('shared.edit'), - edit_admin_question_path(question), - class: "button hollow" %> - <%= link_to t('shared.delete'), + <%= link_to t('admin.polls.show.remove_question'), admin_question_path(question), class: "button hollow alert", method: :delete %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index a99f0d969..edba441f8 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -189,6 +189,7 @@ en: booths_title: "List of booths" officers_title: "List of officers" questions_title: "List of questions" + remove_question: "Remove question from poll" name: "Name" location: "Location" email: "Email" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index d58fa4230..fedb0a4e3 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -185,10 +185,11 @@ es: no_booths: "No hay urnas en esta votación." no_questions: "No hay preguntas asignadas a esta votación todavía." no_officers: "No hay presidentes de mesa asignados." - remove_booth: "Deasignar urna" + remove_booth: "Desasignar urna" booths_title: "Listado de urnas" officers_title: "Listado de presidentes de mesa" questions_title: "Listado de preguntas" + remove_question: "Desasignar pregunta" name: "Nombre" location: "Ubicación" email: "Email" From 71fa9afab8c45038a7982c3a4e522ffa903bd7e7 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 14:09:22 +0100 Subject: [PATCH 179/523] adds edit button on questions show --- app/views/admin/poll/questions/show.html.erb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index ba5b6497b..1bf130359 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -1,8 +1,11 @@ <%= render "shared/back_link" %> +<%= link_to t('shared.edit'), edit_admin_question_path(@question), + class: "button hollow float-right" %> +
    -
    +
    <% if @question.proposal.present? %> <%= t("admin.questions.show.proposal") %> From d45442deed37c3e6e86fb709ff2ba5eb30973b5e Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 14:27:55 +0100 Subject: [PATCH 180/523] changes text on delete position officers --- config/locales/admin.en.yml | 2 +- config/locales/admin.es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index edba441f8..87a8cc75f 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -153,7 +153,7 @@ en: title: Poll officers officer: add: Add - delete: Delete + delete: Delete position name: Name email: Email entry_name: officer diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index fedb0a4e3..183597625 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -153,7 +153,7 @@ es: title: Presidentes de mesa officer: add: Añadir como Presidente de mesa - delete: Borrar + delete: Eliminar cargo name: Nombre email: Email entry_name: presidente de mesa From 772f8ea4addda07d1bf90c33faf4d0e6eb1a8666 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 14:29:28 +0100 Subject: [PATCH 181/523] removes booth name link on booths index --- app/views/admin/poll/booths/_booth.html.erb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/views/admin/poll/booths/_booth.html.erb b/app/views/admin/poll/booths/_booth.html.erb index 5bccfa9c6..5732400a8 100644 --- a/app/views/admin/poll/booths/_booth.html.erb +++ b/app/views/admin/poll/booths/_booth.html.erb @@ -1,8 +1,6 @@
    - - <%= link_to booth.name, admin_booth_path(booth) %> - + <%= booth.name %> <%= booth.location %> From 10c44a077b71897c8cee623e0a47ae10f4396b1d Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 15:19:04 +0100 Subject: [PATCH 182/523] updates specs --- spec/features/admin/poll/booths_spec.rb | 1 - spec/features/admin/poll/officers_spec.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/features/admin/poll/booths_spec.rb b/spec/features/admin/poll/booths_spec.rb index a5fc9e6c0..b84e32b74 100644 --- a/spec/features/admin/poll/booths_spec.rb +++ b/spec/features/admin/poll/booths_spec.rb @@ -40,7 +40,6 @@ feature 'Admin booths' do booth = create(:poll_booth) visit admin_booths_path - click_link booth.name expect(page).to have_content booth.name expect(page).to have_content booth.location diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb index 932bec212..5eac71744 100644 --- a/spec/features/admin/poll/officers_spec.rb +++ b/spec/features/admin/poll/officers_spec.rb @@ -28,7 +28,7 @@ feature 'Admin poll officers' do end scenario 'Delete' do - click_link 'Delete' + click_link 'Delete position' within("#officers") do expect(page).to_not have_content @officer.name From 9c78b60ddc95e5c853ad8ef2ce2a3f56283891e1 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 16 Dec 2016 18:59:15 +0100 Subject: [PATCH 183/523] adds provisional content on booths show and officers assign --- app/assets/stylesheets/admin.scss | 10 +++ app/views/admin/poll/booths/show.html.erb | 87 ++++++++++++++++++- app/views/admin/poll/polls/_officers.html.erb | 62 +++++++++++++ 3 files changed, 155 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index adc166d96..89bed6d21 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -5,6 +5,7 @@ // 03. List elements // 04. Stats // 05. Management +// 06. Polls // // 01. Global styles @@ -474,3 +475,12 @@ table.investment-projects-summary { background: #e0e0e0; } } + +// 06. Polls +// ----------------- + +.count-error { + background: $alert-bg !important; + color: $color-alert; + font-weight: bold; +} diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index 4d21f32e3..c72fd525d 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -3,13 +3,92 @@

    - <%= @booth.name %> + Poll 3: <%= @booth.name %>

    -<%= link_to t("admin.actions.edit"), - edit_admin_booth_path(@booth), - class: "button hollow float-right" %>

    <%= t("admin.booths.show.location") %>: <%= @booth.location %>

    + +
    +
      +
    • + <%= link_to "#tab-officers" do %> + Presidentes de mesa + <% end %> +
    • +
    • + <%= link_to "#tab-count" do %> + Recuentos + <% end %> +
    • +
    + +
    +

    Lista de presidentes de mesa

    + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FechaPresidente de mesaEmail
    13/02/2016Clemente Padilla Oterouser5@consul.dev
    13/02/2016Ana Luisa Ceja Benítezuser7@consul.dev
    14/02/2016Clemente Padilla Oterouser5@consul.dev
    +
    + +
    +

    Lista de recuentos

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FechaVotos (Presidente de mesa)Votos (Admin)
    13/02/2016320320
    14/02/2016160140
    15/02/2016226226
    +
    +
    diff --git a/app/views/admin/poll/polls/_officers.html.erb b/app/views/admin/poll/polls/_officers.html.erb index 11b4cce50..106bff526 100644 --- a/app/views/admin/poll/polls/_officers.html.erb +++ b/app/views/admin/poll/polls/_officers.html.erb @@ -26,3 +26,65 @@
    <% end %> + + +

    Clemente padilla Otero

    +

    user2@consul.dev

    + + +
    + Nuevo turno +
    + + +
    + +
    + + +
    + +
    + +
    +
    + +Añadir nuevo turno + +

    Turnos asignados

    + + + + + + + + + + + + + + + + + + + + + + + + +
    FechaUrna
    13/02/2016Urna Moncloa + <%= link_to "Eliminar turno", "#", class: "button hollow alert" %> +
    14/02/2016Urna Moncloa + <%= link_to "Eliminar turno", "#", class: "button hollow alert" %> +
    15/02/2016Urna Chamartín + <%= link_to "Eliminar turno", "#", class: "button hollow alert" %> +
    + From bc690748fd47f0359ed073c5ce9cabe94d2dea8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 21 Dec 2016 13:50:15 +0100 Subject: [PATCH 184/523] adds dates validation to polls --- app/controllers/admin/poll/polls_controller.rb | 2 +- app/models/poll.rb | 9 +++++++++ app/views/admin/poll/polls/_form.html.erb | 14 ++++++++++---- app/views/admin/poll/polls/show.html.erb | 4 +--- config/locales/activerecord.en.yml | 1 + config/locales/activerecord.es.yml | 1 + spec/features/admin/poll/polls_spec.rb | 2 ++ spec/models/poll/poll_spec.rb | 16 ++++++++++++++++ 8 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 98d74d24f..5eca311a7 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -33,7 +33,7 @@ class Admin::Poll::PollsController < Admin::BaseController private def poll_params - params.require(:poll).permit(:name) + params.require(:poll).permit(:name, :starts_at, :ends_at) end end \ No newline at end of file diff --git a/app/models/poll.rb b/app/models/poll.rb index ceb10d989..4c2fcecb8 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -8,6 +8,8 @@ class Poll < ActiveRecord::Base validates :name, presence: true + validate :date_range + scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.now, Time.now) } scope :incoming, -> { where('? < starts_at', Time.now) } scope :expired, -> { where('ends_at < ?', Time.now) } @@ -38,4 +40,11 @@ class Poll < ActiveRecord::Base def document_has_voted?(document_number, document_type) voters.where(document_number: document_number, document_type: document_type).exists? end + + def date_range + unless starts_at.present? && ends_at.present? && starts_at <= ends_at + errors.add(:starts_at, I18n.t('activerecord.errors.invalid_date_range')) + end + end + end diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 9926c679a..8de8af670 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -9,13 +9,19 @@
    - - + <%= f.label :starts_at, t("admin.polls.form.starts_at") %> + <%= f.text_field :starts_at, + label: false, + value: @poll.starts_at.present? ? l(@poll.starts_at.to_date) : nil, + class: "js-calendar-full" %>
    - - + <%= f.label :ends_at, t("admin.polls.form.ends_at") %> + <%= f.text_field :ends_at, + label: false, + value: @poll.ends_at.present? ? l(@poll.ends_at.to_date) : nil, + class: "js-calendar-full" %>
    diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 5317b1f0a..8bb975729 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -1,8 +1,6 @@ -<%= render "shared/back_link" %> -
    -

    <%= @poll.name %> + <%= l @poll.starts_at.to_date %> - <%= l @poll.ends_at.to_date %>

    <%= link_to t("admin.actions.edit"), diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index b0f06f7df..11e8442e2 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -82,6 +82,7 @@ en: description: "Description" external_url: "Link to additional documentation" errors: + invalid_date_range: "Invalid date range" models: user: attributes: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 2349e9272..8b3407d53 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -82,6 +82,7 @@ es: description: "Descripción" external_url: "Enlace a documentación adicional" errors: + invalid_date_range: "El rango de fechas no es válido" models: user: attributes: diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 5095f36d0..95dc85fde 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -53,6 +53,8 @@ feature 'Admin polls' do click_link "Create poll" fill_in "poll_name", with: "Upcoming poll" + fill_in 'poll_starts_at', with: 1.week.from_now.strftime("%d/%m/%Y") + fill_in 'poll_ends_at', with: 2.weeks.from_now.strftime("%d/%m/%Y") click_button "Create poll" expect(page).to have_content "Poll created successfully" diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index cc6f2c530..1ce3f95e0 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -13,6 +13,22 @@ describe :poll do poll.name = nil expect(poll).to_not be_valid end + + it "should not be valid without a start date" do + poll.starts_at = nil + expect(poll).to_not be_valid + end + + it "should not be valid without an end date" do + poll.ends_at = nil + expect(poll).to_not be_valid + end + + it "should not be valid without a proper start/end date range" do + poll.starts_at = 1.week.ago + poll.ends_at = 2.months.ago + expect(poll).to_not be_valid + end end describe "#opened?" do From 298c9cb76acad1982e31b4d73c7aebe8e3b96f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 21 Dec 2016 14:00:21 +0100 Subject: [PATCH 185/523] adds better spec for poll dates --- spec/features/admin/poll/polls_spec.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 95dc85fde..8db706c01 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -52,13 +52,18 @@ feature 'Admin polls' do visit admin_polls_path click_link "Create poll" + start_date = 1.week.from_now + end_date = 2.weeks.from_now + fill_in "poll_name", with: "Upcoming poll" - fill_in 'poll_starts_at', with: 1.week.from_now.strftime("%d/%m/%Y") - fill_in 'poll_ends_at', with: 2.weeks.from_now.strftime("%d/%m/%Y") + fill_in 'poll_starts_at', with: start_date.strftime("%d/%m/%Y") + fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") click_button "Create poll" expect(page).to have_content "Poll created successfully" expect(page).to have_content "Upcoming poll" + expect(page).to have_content I18n.l(start_date.to_date) + expect(page).to have_content I18n.l(end_date.to_date) end scenario "Edit" do @@ -67,11 +72,15 @@ feature 'Admin polls' do visit admin_poll_path(poll) click_link "Edit" + end_date = 1.year.from_now + fill_in "poll_name", with: "Next Poll" + fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") click_button "Update poll" expect(page).to have_content "Poll updated successfully" expect(page).to have_content "Next Poll" + expect(page).to have_content I18n.l(end_date.to_date) end scenario 'Edit from index' do From 78db093e49ece480b097bfa45e944046da912f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 21 Dec 2016 14:21:02 +0100 Subject: [PATCH 186/523] moves validation error message --- app/models/poll.rb | 2 +- config/locales/activerecord.en.yml | 1 - config/locales/activerecord.es.yml | 1 - config/locales/en.yml | 1 + config/locales/es.yml | 1 + 5 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 4c2fcecb8..72901d9d4 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -43,7 +43,7 @@ class Poll < ActiveRecord::Base def date_range unless starts_at.present? && ends_at.present? && starts_at <= ends_at - errors.add(:starts_at, I18n.t('activerecord.errors.invalid_date_range')) + errors.add(:starts_at, I18n.t('errors.messages.invalid_date_range')) end end diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 11e8442e2..b0f06f7df 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -82,7 +82,6 @@ en: description: "Description" external_url: "Link to additional documentation" errors: - invalid_date_range: "Invalid date range" models: user: attributes: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 8b3407d53..2349e9272 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -82,7 +82,6 @@ es: description: "Descripción" external_url: "Enlace a documentación adicional" errors: - invalid_date_range: "El rango de fechas no es válido" models: user: attributes: diff --git a/config/locales/en.yml b/config/locales/en.yml index f90dac037..4f632166f 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -139,6 +139,7 @@ en: errors: messages: user_not_found: User not found + invalid_date_range: "Invalid date range" form: accept_terms: I agree to the %{policy} and the %{conditions} accept_terms_title: I agree to the Privacy Policy and the Terms and conditions of use diff --git a/config/locales/es.yml b/config/locales/es.yml index fa90809ff..8440d2390 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -139,6 +139,7 @@ es: errors: messages: user_not_found: No se encontró el usuario + invalid_date_range: "El rango de fechas no es válido" form: accept_terms: Acepto la %{policy} y las %{conditions} accept_terms_title: Acepto la Política de privacidad y las Condiciones de uso From a6fbe063c9202a9844bd71b1738c7c801d0d7f7b Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 22 Dec 2016 18:30:39 +0100 Subject: [PATCH 187/523] adds styles to polls index and show views --- app/assets/stylesheets/participation.scss | 79 +++++++++------- app/views/polls/index.html.erb | 34 +++++-- app/views/polls/show.html.erb | 104 ++++++++++++---------- config/locales/en.yml | 2 + config/locales/es.yml | 2 + 5 files changed, 137 insertions(+), 84 deletions(-) diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index 4f0b58bf7..6d9bc4216 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -6,6 +6,7 @@ // 04. List participation // 05. Featured // 06. Proposals successful +// 07. Polls // // 01. Votes and supports @@ -945,37 +946,6 @@ // 06. Proposals successful // ------------------------- -.dark-heading { - background: #2D3E50; - color: white; - - @include breakpoint(medium) { - padding-bottom: $line-height; - } - - &.enquiries { - background: #2D3E50 image-url('heading_enquiries.jpg') no-repeat; - background-position: 70%; - } - - p { - margin-bottom: 0; - - &.title { - color: #FFD200; - } - } - - .info { - background: #314253; - padding-top: $line-height; - - @include breakpoint(medium) { - border-top: rem-calc(6) solid #FFD200; - } - } -} - .sucessfull-proposals-banner { background: #2D3E50 image-url("ballot_tiny.gif") no-repeat; background-position: 75% 0; @@ -1045,3 +1015,50 @@ } } } + +// 07. Polls +// ---------------------- + +.dark-heading { + background: #2D3E50; + color: white; + + .title { + color: #FFD200; + } + + .info { + background: #314253; + padding: $line-height; + + @include breakpoint(medium) { + border-top: rem-calc(6) solid #FFD200; + } + + a { + color: white; + text-decoration: underline; + } + + } + + &.poll-show { + min-height: $line-height*8; + } +} + +.poll, .poll-question { + background: white; + border-bottom: 1px solid $border; + margin-bottom: $line-height/2; + padding: $line-height; + + .date { + color: $brand; + font-size: $small-font-size; + } + + h3 a { + color: $text; + } +} diff --git a/app/views/polls/index.html.erb b/app/views/polls/index.html.erb index b5d98e00f..0b59a17ab 100644 --- a/app/views/polls/index.html.erb +++ b/app/views/polls/index.html.erb @@ -1,7 +1,31 @@ -<%= render 'shared/filter_subnav', i18n_namespace: "polls.index" %> +<% provide :title do %><%= t("polls.index.title") %><% end %> +<% content_for :wrapper_class, "light" %> -<% @polls.each do |poll| %> - <%= link_to poll.name, poll %> (<%= poll_dates(poll) %>) -<% end %> +
    +
    +
    +

    <%= t("polls.index.title") %>

    +
    +
    +
    -<%= paginate @polls %> +
    +
    + <%= render 'shared/filter_subnav_vertical', i18n_namespace: "polls.index" %> +
    + +
    + <% @polls.each do |poll| %> +
    +

    <%= poll.name %>

    +

    <%= poll_dates(poll) %>

    + <%= link_to t("polls.index.button"), + poll, + class: "button", + title: t("polls.index.button") + " " + (poll.name) %> +
    + <% end %> + + <%= paginate @polls %> +
    +
    diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 3006ebc71..63babcfd4 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -1,54 +1,62 @@ -

    <%= @poll.name %>

    -

    <%= t("polls.show.dates_title") %>: <%= poll_dates(@poll) %>

    +<% provide :title do %><%= @poll.name %><% end %> +<% content_for :wrapper_class, "light" %> -<% unless can?(:answer, @poll) %> +
    +
    +
    + <%= render "shared/back_link" %> + +

    <%= @poll.name %>

    +
    +
    +

    + <%= t("polls.show.dates_title") %> +

    +

    + <%= poll_dates(@poll) %> +

    +
    +
    +
    + +
    - <% if current_user.nil? %> -
    - <%= t("polls.show.cant_answer_not_logged_in", - signin: link_to(t("polls.show.signin"), new_user_session_path, class: "probe-message"), - signup: link_to(t("polls.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> -
    - <% elsif current_user.unverified? %> + <% unless can?(:answer, @poll) %> + <% if current_user.nil? %> +
    + <%= t("polls.show.cant_answer_not_logged_in", + signin: link_to(t("polls.show.signin"), new_user_session_path, class: "probe-message"), + signup: link_to(t("polls.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> +
    + <% elsif current_user.unverified? %> +
    + <%= t('polls.show.cant_answer_verify_html', + verify_link: link_to(t('polls.show.verify_link'), verification_path)) %> +
    + <% elsif @poll.incoming? %> +
    + <%= t('polls.show.cant_answer_incoming') %> +
    + <% elsif @poll.expired? %> +
    + <%= t('polls.show.cant_answer_expired') %> +
    + <% end %> + <% end %> + + <% @answerable_questions.each do |question| %> + <%= render 'polls/questions/question', question: question %> + <% end %> + + <% if can?(:answer, @poll) && + @non_answerable_questions.present? %>
    - <%= t('polls.show.cant_answer_verify_html', - verify_link: link_to(t('polls.show.verify_link'), verification_path)) %> -
    - <% elsif @poll.incoming? %> -
    - <%= t('polls.show.cant_answer_incoming') %> -
    - <% elsif @poll.expired? %> -
    - <%= t('polls.show.cant_answer_expired') %> + <%= t('polls.show.cant_answer_wrong_geozone') %>
    <% end %> + + <% @non_answerable_questions.each do |question| %> + <%= render 'polls/questions/question', question: question %> + <% end %>
    -<% end %> - -<% @answerable_questions.each do |question| %> -
    - <%= link_to question.title, question_path(question) %> - -
    - <%= render 'polls/questions/answers', question: question %> -
    -
    -<% end %> - -<% if can?(:answer, @poll) && - @non_answerable_questions.present? %> -
    - <%= t('polls.show.cant_answer_wrong_geozone') %> -
    -<% end %> - -<% @non_answerable_questions.each do |question| %> -
    - <%= link_to question.title, question_path(question) %> - -
    - <%= render 'polls/questions/answers', question: question %> -
    -
    -<% end %> +
    diff --git a/config/locales/en.yml b/config/locales/en.yml index 4f632166f..f4ba4630d 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -387,6 +387,8 @@ en: current: "Open" incoming: "Incoming" expired: "Expired" + title: "Polls" + button: "Participate in this polls" show: dates_title: "Participation dates" cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate." diff --git a/config/locales/es.yml b/config/locales/es.yml index 8440d2390..5464efb80 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -387,6 +387,8 @@ es: current: "Abiertas" incoming: "Próximamente" expired: "Terminadas" + title: "Votaciones" + button: "Participar en esta votación" show: dates_title: "Fechas de participación" cant_answer_not_logged_in: "Necesitas %{signin} o %{signup} para participar." From 8cbd39df697d3d42e319def1001c5df0733d792c Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 22 Dec 2016 18:31:26 +0100 Subject: [PATCH 188/523] adds styles to wrapper and new partial to filter subnav vertical --- app/assets/stylesheets/_settings.scss | 1 + app/assets/stylesheets/layout.scss | 33 +++++++++++++++++-- app/views/layouts/application.html.erb | 2 +- .../shared/_filter_subnav_vertical.html.erb | 14 ++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 app/views/shared/_filter_subnav_vertical.html.erb diff --git a/app/assets/stylesheets/_settings.scss b/app/assets/stylesheets/_settings.scss index 242a03b82..1fa432704 100644 --- a/app/assets/stylesheets/_settings.scss +++ b/app/assets/stylesheets/_settings.scss @@ -79,6 +79,7 @@ $budget: #454372; $budget-hover: #7571BF; $highlight: #E7F2FC; +$light: #F5F7FA; $featured: #FED900; $footer-border: #BFC1C3; diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index c3dded973..106c0e3e6 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -138,6 +138,10 @@ a { padding-top: $line-height; } +.light { + background: $light; +} + .highlight { background: $highlight; } @@ -198,6 +202,30 @@ a { } } +.menu.vertical { + background: white; + margin: $line-height 0; + padding: $line-height; + + li { + margin-bottom: $line-height; + + a { + color: $text-medium; + padding: 0; + } + + h2 { + font-size: $base-font-size; + } + + &.active { + border-bottom: 2px solid $brand; + color: $brand; + } + } +} + .small { font-size: $small-font-size; } @@ -430,6 +458,7 @@ header { .input-group-button { line-height: $line-height*1.5; + padding-bottom: 0; button { background: $border; @@ -451,7 +480,6 @@ header { } .submenu { - background: white; border-bottom: 1px solid $border; clear: both; margin-bottom: $line-height/2; @@ -544,7 +572,8 @@ footer { // 04. Tags // -------- -.tags a , .tag-cloud a, .categories a, .geozone a, .sidebar-links a { +.tags a , .tag-cloud a, .categories a, .geozone a, .sidebar-links a, +.tags span { background: #ececec; border-radius: rem-calc(6); color: $text; diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 35f8729c8..41351f12a 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -22,7 +22,7 @@ <%= setting['per_page_code'].try(:html_safe) %> -
    +
    <%= render 'layouts/header' %> -

    Clemente padilla Otero

    -

    user2@consul.dev

    - - -
    - Nuevo turno -
    - - -
    - -
    - - -
    - -
    - -
    -
    - -Añadir nuevo turno - -

    Turnos asignados

    - - - - - - - - - - - - - - - - - - - - - - - - -
    FechaUrna
    13/02/2016Urna Moncloa - <%= link_to "Eliminar turno", "#", class: "button hollow alert" %> -
    14/02/2016Urna Moncloa - <%= link_to "Eliminar turno", "#", class: "button hollow alert" %> -
    15/02/2016Urna Chamartín - <%= link_to "Eliminar turno", "#", class: "button hollow alert" %> -
    - +<% end %> \ No newline at end of file diff --git a/app/views/admin/poll/polls/_search_officers_results.html.erb b/app/views/admin/poll/polls/_search_officers_results.html.erb index 71fed6589..6225ad9c5 100644 --- a/app/views/admin/poll/polls/_search_officers_results.html.erb +++ b/app/views/admin/poll/polls/_search_officers_results.html.erb @@ -14,7 +14,15 @@ <%= user.email %>
    - + <% if @poll.officer_ids.include?(user.poll_officer.id) %> + <%= link_to t("admin.polls.show.edit_officer_assignments"), + admin_officer_assignments_path(poll: @poll, officer: user.poll_officer), + class: "button hollow alert" %> + <% else %> + <%= link_to t("admin.polls.show.add_officer_assignments"), + admin_officer_assignments_path(poll: @poll, officer: user.poll_officer), + class: "button hollow" %> + <% end %>
    - - - - - - - - <% @officers.each do |officer| %> - - - - - - <% end %> - -
    <%= t('admin.poll_officers.officer.name') %><%= t('admin.poll_officers.officer.email') %>
    - <%= officer.name %> - - <%= officer.email %> - - <% if officer.persisted? %> - <%= link_to t('admin.poll_officers.officer.delete'), - admin_officer_path(officer), - method: :delete, - class: "button hollow alert" - %> - <% else %> - <%= link_to t('admin.poll_officers.officer.add'), - { controller: "admin/poll/officers", action: :create, - user_id: officer.user_id }, - method: :post, - class: "button success" %> - <% end %> -
    +<% if @officers.any? %> + + + + + + + + + <% @officers.each do |officer| %> + + + + + + <% end %> + +
    <%= t('admin.poll_officers.officer.name') %><%= t('admin.poll_officers.officer.email') %>
    + <%= officer.name %> + + <%= officer.email %> + + <% if officer.persisted? %> + <%= link_to t('admin.poll_officers.officer.delete'), + admin_officer_path(officer), + method: :delete, + class: "button hollow alert" + %> + <% else %> + <%= link_to t('admin.poll_officers.officer.add'), + { controller: "admin/poll/officers", action: :create, + user_id: officer.user_id }, + method: :post, + class: "button success" %> + <% end %> +
    -<%= paginate @officers %> + <%= paginate @officers %> +<% end %> \ No newline at end of file From 241ddcb16379352ca5cbede8d3eb31c8b5c33698 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 13:45:36 +0100 Subject: [PATCH 226/523] polish styles for tables, assignments and searches on polls admin --- app/assets/stylesheets/admin.scss | 15 ++++ .../poll/officer_assignments/index.html.erb | 11 ++- app/views/admin/poll/polls/_booths.html.erb | 12 +-- app/views/admin/poll/polls/_officers.html.erb | 2 +- .../admin/poll/polls/_questions.html.erb | 16 +++- .../admin/poll/polls/_search_booths.html.erb | 22 +++--- .../polls/_search_booths_results.html.erb | 76 +++++++++++-------- .../poll/polls/_search_officers.html.erb | 22 +++--- .../polls/_search_officers_results.html.erb | 72 ++++++++++-------- .../poll/polls/_search_questions.html.erb | 22 +++--- .../polls/_search_questions_results.html.erb | 62 +++++++++------ app/views/admin/poll/polls/show.html.erb | 31 +++----- app/views/admin/poll/questions/show.html.erb | 13 ++-- config/locales/admin.en.yml | 18 +++-- config/locales/admin.es.yml | 20 +++-- 15 files changed, 247 insertions(+), 167 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 89bed6d21..8403568a9 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -44,11 +44,22 @@ body.admin { .button { margin-top: 0; + + &.margin-top { + margin-top: $line-height; + } } input[type="text"], textarea { width: 100%; } + + .fieldset { + + select { + height: $line-height*2; + } + } } table { @@ -59,6 +70,10 @@ body.admin { &.text-center { text-align: center; } + + &.text-right { + text-align: right; + } } tr { diff --git a/app/views/admin/poll/officer_assignments/index.html.erb b/app/views/admin/poll/officer_assignments/index.html.erb index 55e879858..81ac5aa61 100644 --- a/app/views/admin/poll/officer_assignments/index.html.erb +++ b/app/views/admin/poll/officer_assignments/index.html.erb @@ -1,4 +1,8 @@ -<%= link_to @poll.name, admin_poll_path(@poll, anchor: 'tab-officers') %> +<%= link_to admin_poll_path(@poll, anchor: 'tab-officers') do %> + + <%= @poll.name %> +<% end %> +

    <%= @officer.name %> - <%= @officer.email %>

    <%= form_tag(admin_officer_assignments_path, {id: "officer_assignment_form"}) do %> @@ -40,7 +44,8 @@ <%= t("admin.poll_officer_assignments.index.date") %> - <%= t("admin.poll_officer_assignments.index.booth") %> + <%= t("admin.poll_officer_assignments.index.booth") %> + <%= t("admin.poll_officer_assignments.index.assignment") %> @@ -48,7 +53,7 @@ <%= l officer_assignment.date.to_date %> <%= booth_name_with_location(officer_assignment.booth_assignment.booth) %> - + <%= link_to t("admin.poll_officer_assignments.index.remove_assignment"), admin_officer_assignment_path(officer_assignment), method: :delete, diff --git a/app/views/admin/poll/polls/_booths.html.erb b/app/views/admin/poll/polls/_booths.html.erb index e955565fd..dbd5de3e1 100644 --- a/app/views/admin/poll/polls/_booths.html.erb +++ b/app/views/admin/poll/polls/_booths.html.erb @@ -5,11 +5,11 @@ <%= t("admin.polls.show.no_booths") %>
    <% else %> - +
    - - - + + + <% @poll.booths.each do |booth| %> @@ -22,7 +22,7 @@ -
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.location") %> <%= t("admin.polls.show.table_name") %><%= t("admin.polls.show.table_location") %><%= t("admin.polls.show.table_assignment") %>
    <%= booth.location %> + <%= link_to t("admin.polls.show.remove_booth"), admin_booth_assignment_path(poll: @poll, booth: booth), method: :delete, @@ -32,4 +32,4 @@ <% end %>
    -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/admin/poll/polls/_officers.html.erb b/app/views/admin/poll/polls/_officers.html.erb index e95d90d24..5f1c1d9c0 100644 --- a/app/views/admin/poll/polls/_officers.html.erb +++ b/app/views/admin/poll/polls/_officers.html.erb @@ -5,7 +5,7 @@ <%= t("admin.polls.show.no_officers") %>
    <% else %> - +
    diff --git a/app/views/admin/poll/polls/_questions.html.erb b/app/views/admin/poll/polls/_questions.html.erb index 8adf3596e..c4dadba49 100644 --- a/app/views/admin/poll/polls/_questions.html.erb +++ b/app/views/admin/poll/polls/_questions.html.erb @@ -5,11 +5,21 @@ <%= t('admin.polls.show.no_questions') %> <% else %> -
    <%= t("admin.polls.show.name") %> <%= t("admin.polls.show.email") %>
    +
    + + + + + + <% @poll.questions.each do |question| %> - - + - <% @poll.booths.each do |booth| %> - + <% @poll.booth_assignments.each do |booth_assignment| %> + diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 310a9142e..3d68b02bb 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -180,6 +180,18 @@ en: remove_assignment: "Remove" assignments: "Officing shifts in this poll" no_assignments: "This user has no officing shifts in this poll." + poll_booth_assignments: + show: + location: "Location" + officers: "Officers" + officers_list: "Officer list for this booth" + no_officers: "There are no officers for this booth" + recounts: "Recounts" + recounts_list: "Recount list for this booth" + no_recounts: "There are not daily recounts of this booth yet" + date: "Date" + count_by_officer: "Votes (by officer)" + count_by_system: "Votes (automatic)" polls: index: title: "List of polls" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index a461d165e..7c93b87da 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -180,6 +180,18 @@ es: remove_assignment: "Eliminar turno" assignments: "Turnos como presidente de mesa en esta votación" no_assignments: "No tiene turnos como presidente de mesa en esta votación." + poll_booth_assignments: + show: + location: "Ubicación" + officers: "Presidentes de mesa" + officers_list: "Lista de presidentes de mesa asignados a esta urna" + no_officers: "No hay presidentes de mesa para esta urna" + recounts: "Recuentos" + recounts_list: "Lista de recuentos de esta urna" + no_recounts: "No hay recuentos diarios de esta urna" + date: "Fecha" + count_by_officer: "Votos (presidente de mesa)" + count_by_system: "Votos (automático)" polls: index: title: "Listado de votaciones" diff --git a/config/routes.rb b/config/routes.rb index ef064513e..52d413730 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -186,15 +186,18 @@ Rails.application.routes.draw do end scope module: :poll do - resources :officers do - get :search, on: :collection - end resources :polls do get :search_booths, on: :member get :search_officers, on: :member get :search_questions, on: :member patch :add_question, on: :member patch :remove_question, on: :member + + resources :booth_assignments, only: :show + end + + resources :officers do + get :search, on: :collection end resources :booths diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 3f21e0089..c7db2b593 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -39,7 +39,7 @@ feature 'Admin booths assignments' do scenario 'remove booth from poll', :js do poll = create(:poll) booth = create(:poll_booth) - create(:poll_booth_assignment, poll: poll, booth: booth) + assignment = create(:poll_booth_assignment, poll: poll, booth: booth) visit admin_poll_path(poll) within('#poll-resources') do @@ -49,7 +49,7 @@ feature 'Admin booths assignments' do expect(page).to_not have_content 'There are no booths assigned to this poll.' expect(page).to have_content booth.name - within("#booth_#{booth.id}") do + within("#poll_booth_assignment_#{assignment.id}") do click_link 'Remove booth from poll' end diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 6f4f60a3d..95bf9bc9a 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -98,7 +98,7 @@ feature 'Admin polls' do context "Poll show" do - scenario "No booths", :js do + scenario "No booths" do poll = create(:poll) visit admin_poll_path(poll) click_link "Booths (0)" @@ -106,7 +106,7 @@ feature 'Admin polls' do expect(page).to have_content "There are no booths assigned to this poll." end - scenario "Booth list", :js do + scenario "Booth list" do poll = create(:poll) 3.times { create(:poll_booth, polls: [poll]) } @@ -115,11 +115,10 @@ feature 'Admin polls' do expect(page).to have_css ".booth", count: 3 - booths = Poll::Booth.all - booths.each do |booth| - within("#booth_#{booth.id}") do - expect(page).to have_content booth.name - expect(page).to have_content booth.location + poll.booth_assignments.each do |ba| + within("#poll_booth_assignment_#{ba.id}") do + expect(page).to have_content ba.booth.name + expect(page).to have_content ba.booth.location end end expect(page).to_not have_content "There are no booths assigned to this poll." From 186be1e7cc7ae4f3115abba9b34fb8a93f56a142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 4 Jan 2017 21:00:55 +0100 Subject: [PATCH 246/523] adds booth_assignments controller to admin menu --- app/helpers/admin_helper.rb | 2 +- app/views/admin/_menu.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 969a8bcad..75f73f80b 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -17,7 +17,7 @@ module AdminHelper end def menu_polls? - ["polls", "questions", "officers", "booths", "officer_assignments"].include? controller_name + ["polls", "questions", "officers", "booths", "officer_assignments", "booth_assignments"].include? controller_name end def menu_profiles? diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 1b4911412..1eb819550 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -60,7 +60,7 @@ <%= t("admin.menu.title_polls") %>
      > -
    • > +
    • > <%= link_to t('admin.menu.polls'), admin_polls_path %>
    • From 0e9cec2ca69c98fbda904b3c06b2311b959631fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 5 Jan 2017 13:00:48 +0100 Subject: [PATCH 247/523] adds spec for recount/officers lists in booth_assignment show --- .../poll/booth_assignments/show.html.erb | 4 +- spec/factories.rb | 8 ++-- .../admin/poll/booth_assigments_spec.rb | 48 ++++++++++++++++++- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/app/views/admin/poll/booth_assignments/show.html.erb b/app/views/admin/poll/booth_assignments/show.html.erb index 01cece32e..e62f17b95 100644 --- a/app/views/admin/poll/booth_assignments/show.html.erb +++ b/app/views/admin/poll/booth_assignments/show.html.erb @@ -30,7 +30,7 @@ <% else %>

      <%= t("admin.poll_booth_assignments.show.officers_list") %>

      -
    <%= t('admin.polls.show.table_title') %><%= t('admin.polls.show.table_assignment') %>
    <%= link_to question.title, admin_question_path(question) %> + + + <%= link_to question.title, admin_question_path(question) %> + + <%= link_to t('admin.polls.show.remove_question'), remove_question_admin_poll_path(poll_id: @poll.id, question_id: question.id), class: "button hollow alert", diff --git a/app/views/admin/poll/polls/_search_booths.html.erb b/app/views/admin/poll/polls/_search_booths.html.erb index e4b038e3a..a02c9e6ec 100644 --- a/app/views/admin/poll/polls/_search_booths.html.erb +++ b/app/views/admin/poll/polls/_search_booths.html.erb @@ -1,12 +1,16 @@ -<%= form_tag(search_booths_admin_poll_path(@poll), method: :get, remote: true) do |f| %> -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.booths_search.placeholder"), id: "search-booths" %> -
    - <%= submit_tag t("admin.shared.booths_search.button"), class: "button" %> -
    +
    +
    + <%= form_tag(search_booths_admin_poll_path(@poll), method: :get, remote: true) do |f| %> +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.booths_search.placeholder"), id: "search-booths" %> +
    + <%= submit_tag t("admin.shared.booths_search.button"), class: "button" %> +
    +
    + <% end %>
    -<% end %> +
    diff --git a/app/views/admin/poll/polls/_search_booths_results.html.erb b/app/views/admin/poll/polls/_search_booths_results.html.erb index 3de4ffca6..3768fa222 100644 --- a/app/views/admin/poll/polls/_search_booths_results.html.erb +++ b/app/views/admin/poll/polls/_search_booths_results.html.erb @@ -1,32 +1,44 @@ - - - - - - - - <% @booths.each do |booth| %> - - - - - - <% end %> - -
    <%= @booths.blank? ? t('admin.polls.show.no_search_results') : t('admin.polls.show.search_results') %>
    - <%= booth.name %> - - <%= booth.location %> - - <% if @poll.booth_ids.include?(booth.id) %> - <%= link_to t("admin.polls.show.remove_booth"), - admin_booth_assignment_path(poll: @poll, booth: booth), - method: :delete, - class: "button hollow alert" %> - <% else %> - <%= link_to t("admin.polls.show.add_booth"), - admin_booth_assignments_path(poll: @poll, booth: booth), - method: :post, - class: "button hollow" %> - <% end %> -
    \ No newline at end of file +<% if @booths.blank? %> +
    + <%= t('admin.polls.show.no_search_results') %> +
    +<% else %> +

    <%= t('admin.polls.show.search_results') %>

    +<% end %> + +<% if @booths.any? %> + + + + + + + + + + <% @booths.each do |booth| %> + + + + + + <% end %> + +
    <%= t("admin.polls.show.table_name") %><%= t("admin.polls.show.table_location") %><%= t("admin.polls.show.table_assignment") %>
    + <%= booth.name %> + + <%= booth.location %> + + <% if @poll.booth_ids.include?(booth.id) %> + <%= link_to t("admin.polls.show.remove_booth"), + admin_booth_assignment_path(poll: @poll, booth: booth), + method: :delete, + class: "button hollow alert" %> + <% else %> + <%= link_to t("admin.polls.show.add_booth"), + admin_booth_assignments_path(poll: @poll, booth: booth), + method: :post, + class: "button hollow" %> + <% end %> +
    +<% end %> diff --git a/app/views/admin/poll/polls/_search_officers.html.erb b/app/views/admin/poll/polls/_search_officers.html.erb index 53d7c1105..b26c98d0c 100644 --- a/app/views/admin/poll/polls/_search_officers.html.erb +++ b/app/views/admin/poll/polls/_search_officers.html.erb @@ -1,12 +1,16 @@ -<%= form_tag(search_officers_admin_poll_path(@poll), method: :get, remote: true) do |f| %> -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.poll_officers_search.placeholder"), id: "search-officers" %> -
    - <%= submit_tag t("admin.shared.poll_officers_search.button"), class: "button" %> -
    +
    +
    + <%= form_tag(search_officers_admin_poll_path(@poll), method: :get, remote: true) do |f| %> +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.poll_officers_search.placeholder"), id: "search-officers" %> +
    + <%= submit_tag t("admin.shared.poll_officers_search.button"), class: "button" %> +
    +
    + <% end %>
    -<% end %> +
    diff --git a/app/views/admin/poll/polls/_search_officers_results.html.erb b/app/views/admin/poll/polls/_search_officers_results.html.erb index 6225ad9c5..818a7fa8d 100644 --- a/app/views/admin/poll/polls/_search_officers_results.html.erb +++ b/app/views/admin/poll/polls/_search_officers_results.html.erb @@ -1,30 +1,42 @@ - - - - - - - - <% @officers.each do |user| %> - - - - - - <% end %> - -
    <%= @officers.blank? ? t('admin.polls.show.no_search_results') : t('admin.polls.show.search_results') %>
    - <%= user.name %> - - <%= user.email %> - - <% if @poll.officer_ids.include?(user.poll_officer.id) %> - <%= link_to t("admin.polls.show.edit_officer_assignments"), - admin_officer_assignments_path(poll: @poll, officer: user.poll_officer), - class: "button hollow alert" %> - <% else %> - <%= link_to t("admin.polls.show.add_officer_assignments"), - admin_officer_assignments_path(poll: @poll, officer: user.poll_officer), - class: "button hollow" %> - <% end %> -
    \ No newline at end of file +<% if @officers.blank? %> +
    + <%= t('admin.polls.show.no_search_results') %> +
    +<% else %> +

    <%= t('admin.polls.show.search_results') %>

    +<% end %> + +<% if @officers.any? %> + + + + + + + + + + <% @officers.each do |user| %> + + + + + + <% end %> + +
    <%= t("admin.polls.show.table_name") %><%= t("admin.polls.show.table_email") %><%= t("admin.polls.show.table_assignment") %>
    + <%= user.name %> + + <%= user.email %> + + <% if @poll.officer_ids.include?(user.poll_officer.id) %> + <%= link_to t("admin.polls.show.edit_officer_assignments"), + admin_officer_assignments_path(poll: @poll, officer: user.poll_officer), + class: "button hollow alert" %> + <% else %> + <%= link_to t("admin.polls.show.add_officer_assignments"), + admin_officer_assignments_path(poll: @poll, officer: user.poll_officer), + class: "button hollow" %> + <% end %> +
    +<% end %> diff --git a/app/views/admin/poll/polls/_search_questions.html.erb b/app/views/admin/poll/polls/_search_questions.html.erb index 2f82d82cf..659cdcd37 100644 --- a/app/views/admin/poll/polls/_search_questions.html.erb +++ b/app/views/admin/poll/polls/_search_questions.html.erb @@ -1,13 +1,17 @@ -<%= form_tag(search_questions_admin_poll_path(@poll), method: :get, remote: true) do |f| %> -
    - <%= text_field_tag :search, - @search, - placeholder: t("admin.shared.poll_questions_search.placeholder"), id: "search-questions" %> +
    +
    + <%= form_tag(search_questions_admin_poll_path(@poll), method: :get, remote: true) do |f| %> +
    + <%= text_field_tag :search, + @search, + placeholder: t("admin.shared.poll_questions_search.placeholder"), id: "search-questions" %> -
    - <%= submit_tag t("admin.shared.poll_questions_search.button"), class: "button" %> -
    +
    + <%= submit_tag t("admin.shared.poll_questions_search.button"), class: "button" %> +
    +
    + <% end %>
    -<% end %> +
    diff --git a/app/views/admin/poll/polls/_search_questions_results.html.erb b/app/views/admin/poll/polls/_search_questions_results.html.erb index e7012edd3..27dcbb652 100644 --- a/app/views/admin/poll/polls/_search_questions_results.html.erb +++ b/app/views/admin/poll/polls/_search_questions_results.html.erb @@ -1,25 +1,37 @@ - - - - - - - - <% @questions.each do |question| %> - - - - - - <% end %> - -
    <%= @questions.blank? ? t('admin.polls.show.no_search_results') : t('admin.polls.show.search_results') %>
    - <%= question.title %> - - <%= question.summary %> - - <%= link_to t("admin.polls.show.add_question"), - add_question_admin_poll_path(poll_id: @poll.id, question_id: question.id), - method: :patch, - class: "button hollow" %> -
    \ No newline at end of file +<% if @questions.blank? %> +
    + <%= t('admin.polls.show.no_search_results') %> +
    +<% else %> +

    <%= t('admin.polls.show.search_results') %>

    +<% end %> + +<% if @questions.any? %> + + + + + + + + + + <% @questions.each do |question| %> + + + + + + <% end %> + +
    <%= t("admin.polls.show.table_name") %><%= t("admin.polls.show.table_summary") %><%= t("admin.polls.show.table_assignment") %>
    + <%= question.title %> + + <%= question.summary %> + + <%= link_to t("admin.polls.show.add_question"), + add_question_admin_poll_path(poll_id: @poll.id, question_id: question.id), + method: :patch, + class: "button hollow" %> +
    +<% end %> diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index 5a59cfa9e..fdc00b949 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -1,39 +1,30 @@ -

    - <%= @poll.name %> - <%= l @poll.starts_at.to_date %> - <%= l @poll.ends_at.to_date %> -

    - <%= link_to t("admin.actions.edit"), edit_admin_poll_path(@poll), class: "button hollow float-right" %> +

    + <%= @poll.name %> +

    +
    +

    + (<%= l @poll.starts_at.to_date %> - <%= l @poll.ends_at.to_date %>) +

    +
    <%= render "filter_subnav" %>
    -
    -
    - <%= render "search_questions" %> -
    -
    + <%= render "search_questions" %> <%= render "questions" %>
    -
    -
    - <%= render "search_booths" %> -
    -
    + <%= render "search_booths" %> <%= render "booths" %>
    -
    -
    - <%= render "search_officers" %> -
    -
    + <%= render "search_officers" %> <%= render 'officers' %>
    \ No newline at end of file diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index 1bf130359..91bf398af 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -7,14 +7,17 @@
    - <% if @question.proposal.present? %> - <%= t("admin.questions.show.proposal") %> - <%= link_to @question.proposal.title, proposal_path(@question.proposal) %> - <% end %> - <%= t("admin.questions.show.title") %>

    <%= @question.title %>

    + <% if @question.proposal.present? %> +

    + <%= t("admin.questions.show.proposal") %> +
    + <%= link_to @question.proposal.title, proposal_path(@question.proposal) %> +

    + <% end %> +

    <%= t("admin.questions.show.author") %>
    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 42613832b..310a9142e 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -173,12 +173,13 @@ en: new_assignment: "New shift" date: "Date" booth: "Booth" + assignment: "Assignment" select_date: "Select day" select_booth: "Select booth" add_assignment: "Add shift" remove_assignment: "Remove" assignments: "Officing shifts in this poll" - no_assignments: "This user has no officing shifts in this poll" + no_assignments: "This user has no officing shifts in this poll." polls: index: title: "List of polls" @@ -200,8 +201,8 @@ en: questions_tab: Questions booths_tab: Booths officers_tab: Officers - no_booths: "There are no booths in this poll." - no_questions: "There are no questions assigned to this poll yet." + no_booths: "There are no booths assigned to this poll." + no_questions: "There are no questions assigned to this poll." no_officers: "There are no officers assigned to this poll." remove_booth: "Remove booth from poll" booths_title: "List of booths" @@ -212,11 +213,14 @@ en: add_question: "Include question" add_officer_assignments: "Add shifts as officer" edit_officer_assignments: "Edit officing shifts" - name: "Name" - location: "Location" - email: "Email" search_results: "Search results" - no_search_results: "No results found" + no_search_results: "No results found." + table_title: "Title" + table_summary: "Summary" + table_assignment: "Assignment" + table_name: "Name" + table_location: "Location" + table_email: "Email" flash: question_added: "Question added to this poll" error_on_question_added: "Question could not be assigned to this poll" diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 6394c6daa..a461d165e 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -173,12 +173,13 @@ es: new_assignment: "Nuevo turno" date: "Fecha" booth: "Urna" + assignment: "Asignación" select_date: "Seleccionar día" select_booth: "Seleccionar urna" add_assignment: "Añadir turno" remove_assignment: "Eliminar turno" assignments: "Turnos como presidente de mesa en esta votación" - no_assignments: "No tiene turnos como presidente de mesa en esta votación" + no_assignments: "No tiene turnos como presidente de mesa en esta votación." polls: index: title: "Listado de votaciones" @@ -200,9 +201,9 @@ es: questions_tab: Preguntas booths_tab: Urnas officers_tab: Presidentes de mesa - no_booths: "No hay urnas en esta votación." - no_questions: "No hay preguntas asignadas a esta votación todavía." - no_officers: "No hay presidentes de mesa asignados." + no_booths: "No hay urnas asignadas a esta votación." + no_questions: "No hay preguntas asignadas a esta votación." + no_officers: "No hay presidentes de mesa asignados a esta votación." remove_booth: "Desasignar urna" booths_title: "Listado de urnas asignadas" officers_title: "Listado de presidentes de mesa asignados" @@ -212,11 +213,14 @@ es: add_question: "Incluir pregunta" add_officer_assignments: "Añadir turnos como presidente de mesa" edit_officer_assignments: "Editar turnos" - name: "Nombre" - location: "Ubicación" - email: "Email" search_results: "Resultados de la búsqueda" - no_search_results: "No se han encontrado resultados" + no_search_results: "No se han encontrado resultados." + table_title: "Título" + table_summary: "Resumen" + table_assignment: "Asignación" + table_name: "Nombre" + table_location: "Ubicación" + table_email: "Email" flash: question_added: "Pregunta añadida a esta votación" error_on_question_added: "No se pudo asignar la pregunta" From f08cbed08034313064711bfbbafb0e18bfd74524 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 13:48:39 +0100 Subject: [PATCH 227/523] adds missing i18n --- app/views/admin/poll/polls/_officers.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/poll/polls/_officers.html.erb b/app/views/admin/poll/polls/_officers.html.erb index 5f1c1d9c0..a3c78c656 100644 --- a/app/views/admin/poll/polls/_officers.html.erb +++ b/app/views/admin/poll/polls/_officers.html.erb @@ -7,8 +7,8 @@ <% else %> - - + + <% @poll.officers.each do |officer| %> From 5c6dfefe0cdae9dc6c4efbdf51a5e8e5c4f57cd9 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 13:56:01 +0100 Subject: [PATCH 228/523] changes color of back link on dark heading --- app/assets/stylesheets/participation.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index a375df091..46332b20e 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -961,7 +961,10 @@ color: white; text-decoration: underline; } + } + .back, .icon-angle-left { + color: white; } &.poll-show { From 4ab9a417fb45ea49287f1413aac89b665d37b497 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 28 Dec 2016 14:04:28 +0100 Subject: [PATCH 229/523] updates specs --- spec/features/admin/poll/booth_assigments_spec.rb | 8 ++++---- spec/features/admin/poll/officers_spec.rb | 4 +--- spec/features/admin/poll/polls_spec.rb | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index ba7f3445a..3f21e0089 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -16,7 +16,7 @@ feature 'Admin booths assignments' do click_link 'Booths (0)' end - expect(page).to have_content 'There are no booths in this poll' + expect(page).to have_content 'There are no booths assigned to this poll.' fill_in 'search-booths', with: booth.name click_button 'Search' @@ -32,7 +32,7 @@ feature 'Admin booths assignments' do click_link 'Booths (1)' end - expect(page).to_not have_content 'There are no booths in this poll' + expect(page).to_not have_content 'There are no booths assigned to this poll.' expect(page).to have_content booth.name end @@ -46,7 +46,7 @@ feature 'Admin booths assignments' do click_link 'Booths (1)' end - expect(page).to_not have_content 'There are no booths in this poll' + expect(page).to_not have_content 'There are no booths assigned to this poll.' expect(page).to have_content booth.name within("#booth_#{booth.id}") do @@ -60,7 +60,7 @@ feature 'Admin booths assignments' do click_link 'Booths (0)' end - expect(page).to have_content 'There are no booths in this poll' + expect(page).to have_content 'There are no booths assigned to this poll.' expect(page).to_not have_content booth.name end end \ No newline at end of file diff --git a/spec/features/admin/poll/officers_spec.rb b/spec/features/admin/poll/officers_spec.rb index 5eac71744..d9ea89638 100644 --- a/spec/features/admin/poll/officers_spec.rb +++ b/spec/features/admin/poll/officers_spec.rb @@ -30,9 +30,7 @@ feature 'Admin poll officers' do scenario 'Delete' do click_link 'Delete position' - within("#officers") do - expect(page).to_not have_content @officer.name - end + expect(page).to_not have_css '#officers' end end \ No newline at end of file diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index 31d7f6128..6f4f60a3d 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -103,7 +103,7 @@ feature 'Admin polls' do visit admin_poll_path(poll) click_link "Booths (0)" - expect(page).to have_content "There are no booths in this poll." + expect(page).to have_content "There are no booths assigned to this poll." end scenario "Booth list", :js do @@ -122,7 +122,7 @@ feature 'Admin polls' do expect(page).to have_content booth.location end end - expect(page).to_not have_content "There are no booths" + expect(page).to_not have_content "There are no booths assigned to this poll." end end end From ca0e6d6694eb08696c1b417a07b33f7fe8d6baf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 28 Dec 2016 20:54:02 +0100 Subject: [PATCH 230/523] adds authorization for poll officers --- app/controllers/officing/base_controller.rb | 18 ++-- spec/features/officing_spec.rb | 109 ++++++++++++++++++++ 2 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 spec/features/officing_spec.rb diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb index 5aeb2431c..271f62daa 100644 --- a/app/controllers/officing/base_controller.rb +++ b/app/controllers/officing/base_controller.rb @@ -1,18 +1,12 @@ -class Officing::BaseController < ActionController::Base +class Officing::BaseController < ApplicationController layout 'admin' - #before_action :verify_officer - before_action :set_locale + before_action :authenticate_user! + before_action :verify_officer - private + skip_authorization_check - def set_locale - if params[:locale] && I18n.available_locales.include?(params[:locale].to_sym) - session[:locale] = params[:locale] - end - - session[:locale] ||= I18n.default_locale - - I18n.locale = session[:locale] + def verify_officer + raise CanCan::AccessDenied unless current_user.try(:poll_officer?) || current_user.try(:administrator?) end end \ No newline at end of file diff --git a/spec/features/officing_spec.rb b/spec/features/officing_spec.rb new file mode 100644 index 000000000..d4cb416a1 --- /dev/null +++ b/spec/features/officing_spec.rb @@ -0,0 +1,109 @@ +require 'rails_helper' + +feature 'Poll Officing' do + let(:user) { create(:user) } + + scenario 'Access as regular user is not authorized' do + login_as(user) + visit root_path + + expect(page).to_not have_link("Polling officers") + visit officing_root_path + + expect(current_path).not_to eq(officing_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as moderator is not authorized' do + create(:moderator, user: user) + login_as(user) + visit root_path + + expect(page).to_not have_link("Polling officers") + visit officing_root_path + + expect(current_path).not_to eq(officing_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as manager is not authorized' do + create(:manager, user: user) + login_as(user) + visit root_path + + expect(page).to_not have_link("Polling officers") + visit officing_root_path + + expect(current_path).not_to eq(officing_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as a valuator is not authorized' do + create(:valuator, user: user) + login_as(user) + visit root_path + + expect(page).to_not have_link("Polling officers") + visit officing_root_path + + expect(current_path).not_to eq(officing_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as an poll officer is authorized' do + create(:poll_officer, user: user) + create(:poll) + login_as(user) + visit root_path + + expect(page).to have_link("Polling officers") + click_on "Polling officers" + + expect(current_path).to eq(officing_root_path) + expect(page).to_not have_content "You do not have permission to access this page" + end + + scenario 'Access as an administrator is authorized' do + create(:administrator, user: user) + create(:poll) + login_as(user) + visit root_path + + expect(page).to have_link("Polling officers") + click_on "Polling officers" + + expect(current_path).to eq(officing_root_path) + expect(page).to_not have_content "You do not have permission to access this page" + end + + scenario "Poll officer access links" do + create(:poll_officer, user: user) + login_as(user) + visit root_path + + expect(page).to have_link("Polling officers") + expect(page).to_not have_link('Valuation') + expect(page).to_not have_link('Administration') + expect(page).to_not have_link('Moderation') + end + + scenario 'Officing dashboard' do + create(:poll_officer, user: user) + create(:poll) + login_as(user) + visit root_path + + click_link 'Polling officers' + + expect(current_path).to eq(officing_root_path) + expect(page).to have_css('#officing_menu') + expect(page).to_not have_css('#valuation_menu') + expect(page).to_not have_css('#admin_menu') + expect(page).to_not have_css('#moderation_menu') + end + +end \ No newline at end of file From 42412e24022dd59505cc8172f6201c90c50e7196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 28 Dec 2016 20:55:16 +0100 Subject: [PATCH 231/523] adds poll_officer case to restricted zones specs --- app/views/officing/_menu.html.erb | 2 +- spec/features/admin_spec.rb | 18 ++++++++++++++---- spec/features/moderation_spec.rb | 14 ++++++++++++++ spec/features/valuation_spec.rb | 13 +++++++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb index f051b5940..889e9b310 100644 --- a/app/views/officing/_menu.html.erb +++ b/app/views/officing/_menu.html.erb @@ -1,5 +1,5 @@
    -
      +
      • > <%= link_to new_officing_poll_voter_path(Poll.last) do %> diff --git a/spec/features/admin_spec.rb b/spec/features/admin_spec.rb index 9ef1b334e..8b72ee839 100644 --- a/spec/features/admin_spec.rb +++ b/spec/features/admin_spec.rb @@ -16,7 +16,7 @@ feature 'Admin' do expect(page).to have_content "You do not have permission to access this page" end - scenario 'Access as a moderator is not authorized' do + scenario 'Access as moderator is not authorized' do create(:moderator, user: user) login_as(user) visit admin_root_path @@ -26,7 +26,7 @@ feature 'Admin' do expect(page).to have_content "You do not have permission to access this page" end - scenario 'Access as a valuator is not authorized' do + scenario 'Access as valuator is not authorized' do create(:valuator, user: user) login_as(user) visit admin_root_path @@ -36,7 +36,7 @@ feature 'Admin' do expect(page).to have_content "You do not have permission to access this page" end - scenario 'Access as a manager is not authorized' do + scenario 'Access as manager is not authorized' do create(:manager, user: user) login_as(user) visit admin_root_path @@ -46,7 +46,17 @@ feature 'Admin' do expect(page).to have_content "You do not have permission to access this page" end - scenario 'Access as an administrator is authorized' do + scenario 'Access as poll officer is not authorized' do + create(:poll_officer, user: user) + login_as(user) + visit admin_root_path + + expect(current_path).not_to eq(admin_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + + scenario 'Access as administrator is authorized' do login_as(administrator) visit admin_root_path diff --git a/spec/features/moderation_spec.rb b/spec/features/moderation_spec.rb index 6607ec48a..fedcb105d 100644 --- a/spec/features/moderation_spec.rb +++ b/spec/features/moderation_spec.rb @@ -43,6 +43,20 @@ feature 'Moderation' do expect(page).to have_content "You do not have permission to access this page" end + scenario 'Access as poll officer is not authorized' do + create(:poll_officer, user: user) + + login_as(user) + visit root_path + + expect(page).to_not have_link("Moderation") + visit moderation_root_path + + expect(current_path).not_to eq(moderation_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + scenario 'Access as a moderator is authorized' do create(:moderator, user: user) diff --git a/spec/features/valuation_spec.rb b/spec/features/valuation_spec.rb index fab16027a..6dc52449c 100644 --- a/spec/features/valuation_spec.rb +++ b/spec/features/valuation_spec.rb @@ -41,6 +41,19 @@ feature 'Valuation' do expect(page).to have_content "You do not have permission to access this page" end + scenario 'Access as poll officer is not authorized' do + create(:poll_officer, user: user) + login_as(user) + visit root_path + + expect(page).to_not have_link("Valuation") + visit valuation_root_path + + expect(current_path).not_to eq(valuation_root_path) + expect(current_path).to eq(proposals_path) + expect(page).to have_content "You do not have permission to access this page" + end + scenario 'Access as a valuator is authorized' do create(:valuator, user: user) login_as(user) From 85b8f54570a00302a49acfbd4aeea121afcdc783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 2 Jan 2017 13:34:53 +0100 Subject: [PATCH 232/523] adds Poll::Recount --- app/models/poll/recount.rb | 9 +++++++++ .../20170102114446_create_poll_recounts.rb | 15 +++++++++++++++ db/schema.rb | 18 +++++++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 app/models/poll/recount.rb create mode 100644 db/migrate/20170102114446_create_poll_recounts.rb diff --git a/app/models/poll/recount.rb b/app/models/poll/recount.rb new file mode 100644 index 000000000..b604ec3a6 --- /dev/null +++ b/app/models/poll/recount.rb @@ -0,0 +1,9 @@ +class Poll + class Recount < ActiveRecord::Base + belongs_to :booth_assignment, class_name: "Poll::BoothAssignment" + belongs_to :officer_assignment, class_name: "Poll::OfficerAssignment" + + validates :officer_assignment_id, presence: true, uniqueness: {scope: :booth_assignment_id} + validates :count, presence: true + end +end \ No newline at end of file diff --git a/db/migrate/20170102114446_create_poll_recounts.rb b/db/migrate/20170102114446_create_poll_recounts.rb new file mode 100644 index 000000000..9643f5b0a --- /dev/null +++ b/db/migrate/20170102114446_create_poll_recounts.rb @@ -0,0 +1,15 @@ +class CreatePollRecounts < ActiveRecord::Migration + def change + create_table :poll_recounts do |t| + t.integer :booth_assignment_id + t.integer :officer_assignment_id + t.integer :count + t.text :count_log, default: "" + + t.timestamps null: false + end + + add_index :poll_recounts, :booth_assignment_id + add_index :poll_recounts, :officer_assignment_id + end +end diff --git a/db/schema.rb b/db/schema.rb index 38e2c7d01..2333356e8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161229110336) do +ActiveRecord::Schema.define(version: 20170102114446) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -123,10 +123,10 @@ ActiveRecord::Schema.define(version: 20161229110336) do t.string "visit_id" t.datetime "hidden_at" t.integer "flags_count", default: 0 - t.datetime "ignored_flag_at" t.integer "cached_votes_total", default: 0 t.integer "cached_votes_up", default: 0 t.integer "cached_votes_down", default: 0 + t.datetime "ignored_flag_at" t.integer "comments_count", default: 0 t.datetime "confirmed_hide_at" t.integer "cached_anonymous_votes_total", default: 0 @@ -336,6 +336,18 @@ ActiveRecord::Schema.define(version: 20161229110336) do add_index "poll_questions", ["proposal_id"], name: "index_poll_questions_on_proposal_id", using: :btree add_index "poll_questions", ["tsv"], name: "index_poll_questions_on_tsv", using: :gin + create_table "poll_recounts", force: :cascade do |t| + t.integer "booth_assignment_id" + t.integer "officer_assignment_id" + t.integer "count" + t.text "count_log", default: "" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "poll_recounts", ["booth_assignment_id"], name: "index_poll_recounts_on_booth_assignment_id", using: :btree + add_index "poll_recounts", ["officer_assignment_id"], name: "index_poll_recounts_on_officer_assignment_id", using: :btree + create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type" @@ -561,7 +573,7 @@ ActiveRecord::Schema.define(version: 20161229110336) do t.boolean "email_digest", default: true t.boolean "email_on_direct_message", default: true t.boolean "official_position_badge", default: false - t.datetime "password_changed_at", default: '2016-12-21 17:55:08', null: false + t.datetime "password_changed_at", default: '2016-11-23 10:59:20', null: false t.boolean "created_from_signature", default: false end From fe1c12c6610a6f71a3bf249971f46445752712d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 2 Jan 2017 13:36:30 +0100 Subject: [PATCH 233/523] updates count_log if recount count value changes --- app/models/poll/recount.rb | 6 ++++++ spec/factories.rb | 6 ++++++ spec/models/poll/recount_spec.rb | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 spec/models/poll/recount_spec.rb diff --git a/app/models/poll/recount.rb b/app/models/poll/recount.rb index b604ec3a6..63745b504 100644 --- a/app/models/poll/recount.rb +++ b/app/models/poll/recount.rb @@ -5,5 +5,11 @@ class Poll validates :officer_assignment_id, presence: true, uniqueness: {scope: :booth_assignment_id} validates :count, presence: true + + before_save :update_count_log + + def update_count_log + self.count_log += ":#{self.count_was.to_s}" if self.count_changed? && self.count_was.present? + end end end \ No newline at end of file diff --git a/spec/factories.rb b/spec/factories.rb index f529e4e84..a9e000e19 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -313,6 +313,12 @@ FactoryGirl.define do date Time.current.to_date end + factory :poll_recount, class: 'Poll::Recount' do + association :officer_assignment, factory: :poll_officer_assignment + association :booth_assignment, factory: :poll_booth_assignment + count (1..100).to_a.sample + end + factory :poll_voter, class: 'Poll::Voter' do association :booth_assignment, factory: :poll_booth_assignment diff --git a/spec/models/poll/recount_spec.rb b/spec/models/poll/recount_spec.rb new file mode 100644 index 000000000..1fe11f7fa --- /dev/null +++ b/spec/models/poll/recount_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe :recount do + + it "should update count_log if count changes" do + recount = create(:poll_recount, count: 33) + + expect(recount.count_log).to eq("") + + recount.count = 33 + recount.save + recount.count = 32 + recount.save + recount.count = 34 + recount.save + + expect(recount.count_log).to eq(":33:32") + end + +end \ No newline at end of file From 1aa845a9c66f7536aa00dc1e886537cb1b8e5d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 2 Jan 2017 18:23:24 +0100 Subject: [PATCH 234/523] adds published to polls --- app/models/poll.rb | 1 + db/migrate/20170102170125_add_published_to_polls.rb | 5 +++++ db/schema.rb | 3 ++- spec/factories.rb | 4 ++++ spec/models/poll/poll_spec.rb | 7 +++++++ 5 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20170102170125_add_published_to_polls.rb diff --git a/app/models/poll.rb b/app/models/poll.rb index 47a955681..79726715e 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -13,6 +13,7 @@ class Poll < ActiveRecord::Base scope :current, -> { where('starts_at <= ? and ? <= ends_at', Time.current, Time.current) } scope :incoming, -> { where('? < starts_at', Time.current) } scope :expired, -> { where('ends_at < ?', Time.current) } + scope :published, -> { where('published = ?', true) } scope :sort_for_list, -> { order(:starts_at) } diff --git a/db/migrate/20170102170125_add_published_to_polls.rb b/db/migrate/20170102170125_add_published_to_polls.rb new file mode 100644 index 000000000..51da03f34 --- /dev/null +++ b/db/migrate/20170102170125_add_published_to_polls.rb @@ -0,0 +1,5 @@ +class AddPublishedToPolls < ActiveRecord::Migration + def change + add_column :polls, :published, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 2333356e8..af72fea7e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170102114446) do +ActiveRecord::Schema.define(version: 20170102170125) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -360,6 +360,7 @@ ActiveRecord::Schema.define(version: 20170102114446) do t.string "name" t.datetime "starts_at" t.datetime "ends_at" + t.boolean "published", default: false end create_table "proposal_notifications", force: :cascade do |t| diff --git a/spec/factories.rb b/spec/factories.rb index a9e000e19..d8b587015 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -282,6 +282,10 @@ FactoryGirl.define do starts_at { 1.month.ago } ends_at { 15.days.ago } end + + trait :published do + published true + end end factory :poll_question, class: 'Poll::Question' do diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index 1ce3f95e0..e410c31ce 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -55,6 +55,13 @@ describe :poll do end end + describe "#published?" do + it "returns true only when published is true" do + expect(create(:poll)).to_not be_published + expect(create(:poll, :published)).to be_published + end + end + describe "#document_has_voted?" do it "returns true if Poll::Voter with document exists" do booth_assignment = create(:poll_booth_assignment, poll: poll) From 55fea6c0370015cebe4eea4f2baa371aae75f2ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 2 Jan 2017 19:29:43 +0100 Subject: [PATCH 235/523] adds polls-related seed data --- db/dev_seeds.rb | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index c03ef2b96..7f8530ee1 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -61,6 +61,9 @@ moderator.create_moderator valuator = create_user('valuator@consul.dev', 'valuator') valuator.create_valuator +poll_officer = create_user('poll_officer@consul.dev', 'Paul O. Fisher') +poll_officer.create_poll_officer + level_2 = create_user('leveltwo@consul.dev', 'level 2') level_2.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_number: "2222222222", document_type: "1" ) @@ -183,7 +186,6 @@ tags = Faker::Lorem.words(25) responsible_name: Faker::Name.name, external_url: Faker::Internet.url, description: description, - created_at: rand((Time.current - 1.week) .. Time.current), tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1", @@ -208,7 +210,6 @@ tags = Faker::Lorem.words(25) tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1", - created_at: 1.month.ago, cached_votes_up: Setting["votes_for_proposal_success"]) puts " #{proposal.title}" end @@ -432,6 +433,20 @@ puts "Creating Poll Booths" Poll::Booth.create(name: "Booth #{i}", polls: [Poll.all.sample]) end +puts "Creating Booth Assignments" +Poll::Booth.all.each do |booth| + Poll::BoothAssignment.create(booth: booth, poll: Poll.all.sample) +end + +puts "Creating Poll Officer Assignments" +(1..10).to_a.sample.times do |i| + Poll::BoothAssignment.all.sample(i).each do |booth_assignment| + Poll::OfficerAssignment.create(officer: poll_officer, + booth_assignment: booth_assignment, + date: booth_assignment.poll.starts_at) + end +end + puts "Creating Poll Question from Proposals" (1..3).each do |i| From b3fd7ffafa64a48fc0a314baab42107882c2ea8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 2 Jan 2017 20:28:16 +0100 Subject: [PATCH 236/523] adds assigned_polls method to poll_officer --- app/models/poll/officer.rb | 7 +++++ spec/models/poll/officer_spec.rb | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 spec/models/poll/officer_spec.rb diff --git a/app/models/poll/officer.rb b/app/models/poll/officer.rb index 48a9e171c..14eec442f 100644 --- a/app/models/poll/officer.rb +++ b/app/models/poll/officer.rb @@ -6,5 +6,12 @@ class Poll validates :user_id, presence: true, uniqueness: true delegate :name, :email, to: :user + + def assigned_polls + officer_assignments.includes(booth_assignment: :poll). + map(&:booth_assignment). + map(&:poll).uniq.compact. + sort {|x, y| y.ends_at <=> x.ends_at} + end end end \ No newline at end of file diff --git a/spec/models/poll/officer_spec.rb b/spec/models/poll/officer_spec.rb new file mode 100644 index 000000000..cea0e8bae --- /dev/null +++ b/spec/models/poll/officer_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +describe :officer do + + describe "#assigned_polls" do + it "should return all polls with this officer assigned" do + officer = create(:poll_officer) + + poll_1 = create(:poll) + poll_2 = create(:poll) + poll_3 = create(:poll) + + booth_assignment_1a = create(:poll_booth_assignment, poll: poll_1) + booth_assignment_1b = create(:poll_booth_assignment, poll: poll_1) + booth_assignment_2 = create(:poll_booth_assignment, poll: poll_2) + + create(:poll_officer_assignment, booth_assignment: booth_assignment_1a, officer: officer, date: poll_1.starts_at) + create(:poll_officer_assignment, booth_assignment: booth_assignment_1b, officer: officer, date: poll_1.ends_at) + create(:poll_officer_assignment, booth_assignment: booth_assignment_2, officer: officer) + + assigned_polls = officer.assigned_polls + expect(assigned_polls.size).to eq 2 + expect(assigned_polls.include?(poll_1)).to eq(true) + expect(assigned_polls.include?(poll_2)).to eq(true) + expect(assigned_polls.include?(poll_3)).to eq(false) + end + + it "should return polls ordered by end date (desc)" do + officer = create(:poll_officer) + + poll_1 = create(:poll, ends_at: 1.day.ago) + poll_2 = create(:poll, ends_at: 10.days.from_now) + poll_3 = create(:poll, ends_at: 10.day.ago) + + [poll_1, poll_2, poll_3].each do |p| + create(:poll_officer_assignment, officer: officer, booth_assignment: create(:poll_booth_assignment, poll: p)) + end + + assigned_polls = officer.assigned_polls + + expect(assigned_polls.first).to eq(poll_2) + expect(assigned_polls.second).to eq(poll_1) + expect(assigned_polls.last).to eq(poll_3) + end + end + +end \ No newline at end of file From 0c1d7c15c1b80b9a617c28f633c7da00c51273f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 21:30:03 +0100 Subject: [PATCH 237/523] adds date and officer log to recounts --- ...date_and_officer_assignment_log_to_poll_recounts.rb | 6 ++++++ db/schema.rb | 10 ++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20170103191711_add_date_and_officer_assignment_log_to_poll_recounts.rb diff --git a/db/migrate/20170103191711_add_date_and_officer_assignment_log_to_poll_recounts.rb b/db/migrate/20170103191711_add_date_and_officer_assignment_log_to_poll_recounts.rb new file mode 100644 index 000000000..e0f813500 --- /dev/null +++ b/db/migrate/20170103191711_add_date_and_officer_assignment_log_to_poll_recounts.rb @@ -0,0 +1,6 @@ +class AddDateAndOfficerAssignmentLogToPollRecounts < ActiveRecord::Migration + def change + add_column :poll_recounts, :date, :datetime + add_column :poll_recounts, :officer_assignment_id_log, :text, default: "" + end +end diff --git a/db/schema.rb b/db/schema.rb index af72fea7e..530344ce1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170102170125) do +ActiveRecord::Schema.define(version: 20170103191711) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -340,9 +340,11 @@ ActiveRecord::Schema.define(version: 20170102170125) do t.integer "booth_assignment_id" t.integer "officer_assignment_id" t.integer "count" - t.text "count_log", default: "" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.text "count_log", default: "" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.datetime "date" + t.text "officer_assignment_id_log", default: "" end add_index "poll_recounts", ["booth_assignment_id"], name: "index_poll_recounts_on_booth_assignment_id", using: :btree From 8b56403bb19842b935ca35c4c6a519d198b553d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 21:35:04 +0100 Subject: [PATCH 238/523] adds validations and info logging to Recount --- app/models/poll/recount.rb | 13 +++++++++---- spec/models/poll/recount_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/app/models/poll/recount.rb b/app/models/poll/recount.rb index 63745b504..b4e28583e 100644 --- a/app/models/poll/recount.rb +++ b/app/models/poll/recount.rb @@ -3,13 +3,18 @@ class Poll belongs_to :booth_assignment, class_name: "Poll::BoothAssignment" belongs_to :officer_assignment, class_name: "Poll::OfficerAssignment" + validates :booth_assignment_id, presence: true + validates :date, presence: true, uniqueness: {scope: :booth_assignment_id} validates :officer_assignment_id, presence: true, uniqueness: {scope: :booth_assignment_id} - validates :count, presence: true + validates :count, presence: true, numericality: {only_integer: true} - before_save :update_count_log + before_save :update_logs - def update_count_log - self.count_log += ":#{self.count_was.to_s}" if self.count_changed? && self.count_was.present? + def update_logs + if self.count_changed? && self.count_was.present? + self.count_log += ":#{self.count_was.to_s}" + self.officer_assignment_id_log += ":#{self.officer_assignment_id_was.to_s}" + end end end end \ No newline at end of file diff --git a/spec/models/poll/recount_spec.rb b/spec/models/poll/recount_spec.rb index 1fe11f7fa..2d6bf5336 100644 --- a/spec/models/poll/recount_spec.rb +++ b/spec/models/poll/recount_spec.rb @@ -17,4 +17,24 @@ describe :recount do expect(recount.count_log).to eq(":33:32") end + it "should update officer_assignment_id_log if count changes" do + recount = create(:poll_recount, count: 33) + + expect(recount.count_log).to eq("") + + recount.count = 33 + recount.officer_assignment_id = 1 + recount.save + + recount.count = 32 + recount.officer_assignment_id = 2 + recount.save + + recount.count = 34 + recount.officer_assignment_id = 3 + recount.save + + expect(recount.officer_assignment_id_log).to eq(":1:2") + end + end \ No newline at end of file From 8d522241210f0042c00ca4cfd44fb00f569de875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 22:17:27 +0100 Subject: [PATCH 239/523] removes unused routes/files --- app/views/officing/results/index.html.erb | 54 ----------------------- app/views/officing/results/show.html.erb | 50 --------------------- config/locales/officing.en.yml | 17 ------- config/locales/officing.es.yml | 17 ------- 4 files changed, 138 deletions(-) delete mode 100644 app/views/officing/results/index.html.erb delete mode 100644 app/views/officing/results/show.html.erb diff --git a/app/views/officing/results/index.html.erb b/app/views/officing/results/index.html.erb deleted file mode 100644 index 8e50de625..000000000 --- a/app/views/officing/results/index.html.erb +++ /dev/null @@ -1,54 +0,0 @@ -

        <%= t("officing.results.index.title") %>

        - -
        -
        - -
        - -
        - -
        - -
        - -
        -
        - -
    <%= t("admin.polls.show.name") %><%= t("admin.polls.show.email") %><%= t("admin.polls.show.table_name") %><%= t("admin.polls.show.table_email") %>
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    <%= t("officing.shared.booth") %><%= t("officing.shared.date") %><%= t("officing.shared.officer") %><%= t("officing.shared.votes_number") %>
    <%= link_to "Urna Moncloa (1)", officing_poll_result_path(Poll.last, 1) %>14/10/2016Officer Name (officer@email.com)124
    <%= link_to "Urna Cahamartín (6)", officing_poll_result_path(Poll.last, 1) %>17/10/2016Other Officer (otherofficer@email.com)350
    <%= t("officing.results.index.total_votes") %>474
    diff --git a/app/views/officing/results/show.html.erb b/app/views/officing/results/show.html.erb deleted file mode 100644 index 4c7b88e00..000000000 --- a/app/views/officing/results/show.html.erb +++ /dev/null @@ -1,50 +0,0 @@ -<%= render 'shared/back_link' %> - -

    <%= t("officing.results.show.title", booth: "Booth Name (1)") %>

    - -
    -
    - -
    - -
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    <%= t("officing.shared.date") %><%= t("officing.shared.officer") %><%= t("officing.shared.votes_number") %>
    14/10/2016Officer Name (officer@email.com)124
    17/10/2016Other Officer (otherofficer@email.com)350
    18/10/2016Officer number 3 (officer3@email.com)100
    <%= t("officing.results.index.total_votes") %>574
    diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index 20cd8fcfc..a477c793e 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -25,20 +25,3 @@ en: can_participate: "The person associated with the document can participate in the vote." submit: Validate vote success: "Vote validated correctly." - results: - index: - title: "Vote results" - total_votes: "Total number of votes" - new: - title: Save results - submit: Save - show: - title: "%{booth} results" - shared: - filter_booth: All booths - filter_date: All dates - filter_officer: All officers - booth: Booth - date: Date - officer: Officer - votes_number: Number of votes diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index e187365f1..6a49184c6 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -25,20 +25,3 @@ es: can_participate: "La persona asociada al documento puede participar en la votación." submit: Validar voto success: "Voto validado correctamente." - results: - index: - title: "Resultados de la votación" - total_votes: "Número total de votos" - new: - title: Guardar resultados - submit: Guardar - show: - title: "Resultados de %{booth}" - shared: - filter_booth: Todas las urnas - filter_date: Todas las fechas - filter_officer: Todos los presidentes de mesa - booth: Urna - date: Fecha - officer: Presidente de mesa - votes_number: Número de votos From 2886d6d9545806aa6c01229798aba676e5d12d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 22:20:22 +0100 Subject: [PATCH 240/523] adds relations to officer/booth assignments --- app/models/poll/booth_assignment.rb | 1 + app/models/poll/officer_assignment.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/models/poll/booth_assignment.rb b/app/models/poll/booth_assignment.rb index 3c3d3d0d0..9460533fa 100644 --- a/app/models/poll/booth_assignment.rb +++ b/app/models/poll/booth_assignment.rb @@ -4,6 +4,7 @@ class Poll belongs_to :poll has_many :officer_assignments, class_name: "Poll::OfficerAssignment", dependent: :destroy + has_many :recounts, class_name: "Poll::Recount", dependent: :destroy has_many :officers, through: :officer_assignments has_many :voters end diff --git a/app/models/poll/officer_assignment.rb b/app/models/poll/officer_assignment.rb index 3ef0ee2db..e192780cc 100644 --- a/app/models/poll/officer_assignment.rb +++ b/app/models/poll/officer_assignment.rb @@ -2,6 +2,7 @@ class Poll class OfficerAssignment < ActiveRecord::Base belongs_to :officer belongs_to :booth_assignment + has_one :recount validates :officer_id, presence: true validates :booth_assignment_id, presence: true From 09dac72471347fa32a7076ce771fe822a3d9a9c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 22:22:52 +0100 Subject: [PATCH 241/523] adds officing's polls index --- app/controllers/officing/polls_controller.rb | 8 ++++++ app/models/poll/officer.rb | 1 + app/views/officing/_menu.html.erb | 6 ++-- app/views/officing/polls/index.html.erb | 30 ++++++++++++++++++++ config/locales/officing.en.yml | 8 +++++- config/locales/officing.es.yml | 10 +++++-- config/routes.rb | 2 +- 7 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 app/controllers/officing/polls_controller.rb create mode 100644 app/views/officing/polls/index.html.erb diff --git a/app/controllers/officing/polls_controller.rb b/app/controllers/officing/polls_controller.rb new file mode 100644 index 000000000..0634bccb5 --- /dev/null +++ b/app/controllers/officing/polls_controller.rb @@ -0,0 +1,8 @@ +class Officing::PollsController < Officing::BaseController + + def index + @polls = current_user.poll_officer? ? current_user.poll_officer.assigned_polls : [] + @polls = @polls.select {|poll| poll.current?(1.day.ago)} + end + +end \ No newline at end of file diff --git a/app/models/poll/officer.rb b/app/models/poll/officer.rb index 14eec442f..138a582fc 100644 --- a/app/models/poll/officer.rb +++ b/app/models/poll/officer.rb @@ -13,5 +13,6 @@ class Poll map(&:poll).uniq.compact. sort {|x, y| y.ends_at <=> x.ends_at} end + end end \ No newline at end of file diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb index 889e9b310..d999fc06b 100644 --- a/app/views/officing/_menu.html.erb +++ b/app/views/officing/_menu.html.erb @@ -8,10 +8,10 @@ <% end %> -
  • > - <%= link_to new_officing_poll_result_path(Poll.last) do %> +
  • > + <%= link_to officing_polls_path do %> - <%= t("officing.menu.results") %> + <%= t("officing.menu.recounts") %> <% end %>
  • diff --git a/app/views/officing/polls/index.html.erb b/app/views/officing/polls/index.html.erb new file mode 100644 index 000000000..8f3e4921e --- /dev/null +++ b/app/views/officing/polls/index.html.erb @@ -0,0 +1,30 @@ +

    <%= t("officing.polls.index.title") %>

    + +<% if @polls.any? %> + + + + + + + <% @polls.each do |poll| %> + + + + + <% end %> + +
    <%= t("officing.polls.index.select_poll") %> 
    + + <%= link_to poll.name, new_officing_poll_recount_path(poll) %> + + + <%= link_to t("officing.polls.index.add_recount"), + new_officing_poll_recount_path(poll), + class: "button hollow" %> +
    +<% else %> +
    + <%= t("officing.polls.index.no_polls") %> +
    +<% end %> \ No newline at end of file diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index a477c793e..87d4e77c4 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -7,7 +7,13 @@ en: info: Here you can validate user documents and store voting results menu: voters: Validate document - results: Store results + recounts: Store recount + polls: + index: + title: Poll list + no_polls: You are not officing in any active poll + select_poll: Select poll + add_recount: Add recount voters: new: title: Validate document diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index 6a49184c6..0831ba821 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -6,8 +6,14 @@ es: title: Presidir mesa de votaciones info: Aquí puedes validar documentos de ciudadanos y guardar los resultados de las urnas menu: - voters: Validar documento - results: Guardar resultados + voters: "Validar documento" + recounts: "Guardar recuento" + polls: + index: + title: "Listado de votaciones" + no_polls: "No eres presidente de mesa en ninguna votación activa" + select_poll: "Selecciona votación" + add_recount: "Añadir recuento" voters: new: title: Validar documento diff --git a/config/routes.rb b/config/routes.rb index bc6e719d0..98011d005 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -289,7 +289,7 @@ Rails.application.routes.draw do end namespace :officing do - resources :polls do + resources :polls, only: [:index] do resources :voters, only: [:new, :show] resources :results, only: [:new, :index, :show] end From 0953a536af55cf9b35a9d109cff6adbcea52837b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 22:23:54 +0100 Subject: [PATCH 242/523] adds recounting to officing --- .../officing/recounts_controller.rb | 45 +++++++++++++ .../officing/results_controller.rb | 15 ----- app/controllers/officing/voters_controller.rb | 3 - app/helpers/officing_helper.rb | 11 ++++ app/views/officing/recounts/new.html.erb | 63 +++++++++++++++++++ app/views/officing/results/new.html.erb | 38 ----------- config/locales/officing.en.yml | 15 +++++ config/locales/officing.es.yml | 15 +++++ config/routes.rb | 2 +- 9 files changed, 150 insertions(+), 57 deletions(-) create mode 100644 app/controllers/officing/recounts_controller.rb delete mode 100644 app/controllers/officing/results_controller.rb create mode 100644 app/helpers/officing_helper.rb create mode 100644 app/views/officing/recounts/new.html.erb delete mode 100644 app/views/officing/results/new.html.erb diff --git a/app/controllers/officing/recounts_controller.rb b/app/controllers/officing/recounts_controller.rb new file mode 100644 index 000000000..0e0a79d69 --- /dev/null +++ b/app/controllers/officing/recounts_controller.rb @@ -0,0 +1,45 @@ +class Officing::RecountsController < Officing::BaseController + before_action :load_poll + before_action :load_officer_assignment, only: :create + + def new + @officer_assignments = ::Poll::OfficerAssignment. + includes(:recount, booth_assignment: :booth). + joins(:booth_assignment). + where(id: current_user.poll_officer.officer_assignment_ids). + where("poll_booth_assignments.poll_id = ?", @poll.id). + order(date: :asc) + @recounted = @officer_assignments.select {|oa| oa.recount.present?}.reverse + end + + def create + @recount = ::Poll::Recount.find_or_initialize_by(booth_assignment_id: @officer_assignment.booth_assignment_id, date: @officer_assignment.date) + @recount.officer_assignment_id = @officer_assignment.id + @recount.count = recount_params[:count] + + if @recount.save + notice = t("officing.recounts.flash.create") + else + notice = t("officing.recounts.flash.error_create") + end + redirect_to new_officing_poll_recount_path(@poll), notice: notice + end + + private + def load_poll + @poll = Poll.current.find(params[:poll_id]) + end + + def load_officer_assignment + @officer_assignment = current_user.poll_officer. + officer_assignments.find_by(id: recount_params[:officer_assignment_id]) + if @officer_assignment.blank? + redirect_to new_officing_poll_recount_path(@poll), notice: t("officing.recounts.flash.error_create") + end + end + + def recount_params + params.permit(:officer_assignment_id, :count) + end + +end \ No newline at end of file diff --git a/app/controllers/officing/results_controller.rb b/app/controllers/officing/results_controller.rb deleted file mode 100644 index 03e638366..000000000 --- a/app/controllers/officing/results_controller.rb +++ /dev/null @@ -1,15 +0,0 @@ -class Officing::ResultsController < Officing::BaseController - layout 'admin' - - before_action :authenticate_user! - - def index - end - - def show - end - - def new - end - -end \ No newline at end of file diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb index 6d7ad8512..6cf321beb 100644 --- a/app/controllers/officing/voters_controller.rb +++ b/app/controllers/officing/voters_controller.rb @@ -1,7 +1,4 @@ class Officing::VotersController < Officing::BaseController - layout 'admin' - - before_action :authenticate_user! def new end diff --git a/app/helpers/officing_helper.rb b/app/helpers/officing_helper.rb new file mode 100644 index 000000000..d1436c515 --- /dev/null +++ b/app/helpers/officing_helper.rb @@ -0,0 +1,11 @@ +module OfficingHelper + + def officer_assignments_select_options(officer_assignments) + options = [] + officer_assignments.each do |oa| + options << ["#{oa.booth_assignment.booth.name}: #{l(oa.date.to_date, format: :long)}", oa.id] + end + options_for_select(options) + end + +end \ No newline at end of file diff --git a/app/views/officing/recounts/new.html.erb b/app/views/officing/recounts/new.html.erb new file mode 100644 index 000000000..dc78ccf89 --- /dev/null +++ b/app/views/officing/recounts/new.html.erb @@ -0,0 +1,63 @@ +<% if @officer_assignments.any? %> +

    <%= t("officing.recounts.new.title", poll: @poll.name) %>

    + + <%= form_tag(officing_poll_recounts_path(@poll), {id: "officer_assignment_form"}) do %> + +
    +
    + + <%= select_tag :officer_assignment_id, + officer_assignments_select_options(@officer_assignments), + { prompt: t("officing.recounts.new.select_booth_date"), + label: false } %> +
    +
    + +
    +
    + + <%= text_field_tag :count, nil, placeholder: t("officing.recounts.new.count_placeholder") %> +
    +
    + +
    +
    + <%= submit_tag t("officing.recounts.new.submit"), class: "button expanded" %> +
    +
    + <% end %> +<% else %> +

    <%= @poll.name %>

    +
    + <%= t("officing.recounts.new.not_allowed") %> +
    +<% end %> + + +<% if @recounted.any? %> +
    +

    <%= t("officing.recounts.new.recount_list") %>

    + + + + + + + + + <% @recounted.each do |oa| %> + + + + + + <% end %> + +
    <%= t("officing.recounts.new.date") %><%= t("officing.recounts.new.booth") %><%= t("officing.recounts.new.count") %>
    + <%= l(oa.date.to_date, format: :long) %> + + <%= oa.booth_assignment.booth.name %> + + <%= oa.recount.count %> +
    +<% end %> diff --git a/app/views/officing/results/new.html.erb b/app/views/officing/results/new.html.erb deleted file mode 100644 index 178efbadd..000000000 --- a/app/views/officing/results/new.html.erb +++ /dev/null @@ -1,38 +0,0 @@ -

    <%= t("officing.results.new.title") %>

    - -
    - -
    -
    - - -
    - -
    - - -
    -
    - -
    -
    - - -
    -
    - -
    - -
    -
    - - "> -
    -
    - -
    -
    - " class="button expanded"> -
    -
    -
    diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index 87d4e77c4..fad63ee4e 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -14,6 +14,21 @@ en: no_polls: You are not officing in any active poll select_poll: Select poll add_recount: Add recount + recounts: + flash: + create: "Data added" + error_create: "Count NOT added. Error in data." + new: + title: "%{poll} - Add daily recount" + not_allowed: "You are not a poll officer for this poll" + booth_date: "Booth and date" + select_booth_date: "Select booth and date" + count: "Vote count" + count_placeholder: "Vote count" + submit: Save + recount_list: "Your recounts" + booth: "Booth" + date: "Date" voters: new: title: Validate document diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index 0831ba821..1a8bccb13 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -14,6 +14,21 @@ es: no_polls: "No eres presidente de mesa en ninguna votación activa" select_poll: "Selecciona votación" add_recount: "Añadir recuento" + recounts: + flash: + create: "Datos añadidos" + error_create: "Recuento NO añadido. Error en los datos" + new: + title: "%{poll} - Añadir recuento diario" + not_allowed: "No eres presidente de mesa en esta votación" + booth_date: "Fecha y urna" + select_booth_date: "Elige fecha y urna" + count: "Número de votos" + count_placeholder: "Número de votos" + submit: "Guardar" + recount_list: "Tus recuentos" + booth: "Urna" + date: "Fecha" voters: new: title: Validar documento diff --git a/config/routes.rb b/config/routes.rb index 98011d005..ef064513e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -290,8 +290,8 @@ Rails.application.routes.draw do namespace :officing do resources :polls, only: [:index] do + resources :recounts, only: [:new, :create] resources :voters, only: [:new, :show] - resources :results, only: [:new, :index, :show] end root to: "dashboard#index" end From c2a61096aa24333674d583621ea31e69fb88da8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 3 Jan 2017 23:02:58 +0100 Subject: [PATCH 243/523] adds required date to recount factory fixes recount spec --- spec/factories.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/factories.rb b/spec/factories.rb index d8b587015..9f086ab8e 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -321,6 +321,7 @@ FactoryGirl.define do association :officer_assignment, factory: :poll_officer_assignment association :booth_assignment, factory: :poll_booth_assignment count (1..100).to_a.sample + date (1.month.ago.to_datetime..1.month.from_now.to_datetime).to_a.sample end factory :poll_voter, class: 'Poll::Voter' do From 909dce00e0084a66617ed379cdd10afb99af0470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 4 Jan 2017 13:52:11 +0100 Subject: [PATCH 244/523] adds recounting spec --- spec/features/officing/recount_spec.rb | 87 ++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 spec/features/officing/recount_spec.rb diff --git a/spec/features/officing/recount_spec.rb b/spec/features/officing/recount_spec.rb new file mode 100644 index 000000000..a7d74d0be --- /dev/null +++ b/spec/features/officing/recount_spec.rb @@ -0,0 +1,87 @@ +require 'rails_helper' + +feature 'Officing Recount' do + + background do + @poll_officer = create(:poll_officer) + @officer_assignment = create(:poll_officer_assignment, officer: @poll_officer) + @poll = @officer_assignment.booth_assignment.poll + login_as(@poll_officer.user) + end + + scenario 'Only polls where user is officer are accessible' do + not_allowed_poll = create(:poll) + + visit root_path + click_link 'Polling officers' + + expect(page).to have_content('Poll officing') + within('#side_menu') do + click_link 'Store recount' + end + + expect(page).to_not have_content(not_allowed_poll.name) + expect(page).to have_content(@poll.name) + + visit new_officing_poll_recount_path(not_allowed_poll) + expect(page).to have_content('You are not a poll officer for this poll') + end + + scenario 'Add recount' do + visit officing_root_path + + within('#side_menu') do + click_link 'Store recount' + end + + click_link @poll.name + + expect(page).to_not have_content('Your recounts') + + booth_name = @officer_assignment.booth_assignment.booth.name + date = I18n.l(@officer_assignment.date.to_date, format: :long) + select "#{booth_name}: #{date}", from: 'officer_assignment_id' + fill_in :count, with: '33' + click_button 'Save' + + expect(page).to have_content('Your recounts') + + within("#poll_recount_#{@officer_assignment.booth_assignment.recounts.first.id}") do + expect(page).to have_content(date) + expect(page).to have_content(booth_name) + expect(page).to have_content('33') + end + end + + scenario 'Edit recount' do + recount = create(:poll_recount, + officer_assignment: @officer_assignment, + booth_assignment: @officer_assignment.booth_assignment, + date: @officer_assignment.date, + count: 100) + + booth_name = @officer_assignment.booth_assignment.booth.name + date = I18n.l(@officer_assignment.date.to_date, format: :long) + + visit new_officing_poll_recount_path(@poll) + + expect(page).to have_content('Your recounts') + + within("#poll_recount_#{recount.id}") do + expect(page).to have_content(date) + expect(page).to have_content(booth_name) + expect(page).to have_content('100') + end + + select "#{booth_name}: #{date}", from: 'officer_assignment_id' + fill_in :count, with: '42' + click_button 'Save' + + within("#poll_recount_#{recount.id}") do + expect(page).to have_content(date) + expect(page).to have_content(booth_name) + expect(page).to have_content('42') + end + expect(page).to_not have_content('100') + end +end \ No newline at end of file From 70b86170a256e42345632d8995911d0839975898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 4 Jan 2017 21:00:36 +0100 Subject: [PATCH 245/523] adds booth_assignment show with officers and recounts info --- .../poll/booth_assignments_controller.rb | 11 ++- .../admin/poll/polls_controller.rb | 2 +- .../poll/booth_assignments/show.html.erb | 73 ++++++++++++++++ app/views/admin/poll/booths/show.html.erb | 84 +------------------ app/views/admin/poll/polls/_booths.html.erb | 12 +-- config/locales/admin.en.yml | 12 +++ config/locales/admin.es.yml | 12 +++ config/routes.rb | 9 +- .../admin/poll/booth_assigments_spec.rb | 4 +- spec/features/admin/poll/polls_spec.rb | 13 ++- 10 files changed, 127 insertions(+), 105 deletions(-) create mode 100644 app/views/admin/poll/booth_assignments/show.html.erb diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb index f09213c82..0f01ab462 100644 --- a/app/controllers/admin/poll/booth_assignments_controller.rb +++ b/app/controllers/admin/poll/booth_assignments_controller.rb @@ -1,7 +1,5 @@ class Admin::Poll::BoothAssignmentsController < Admin::BaseController - before_action :load_booth_assignment, only: :destroy - def create @booth_assignment = ::Poll::BoothAssignment.new(poll_id: booth_assignment_params[:poll], booth_id: booth_assignment_params[:booth]) @@ -14,6 +12,8 @@ class Admin::Poll::BoothAssignmentsController < Admin::BaseController end def destroy + @booth_assignment = ::Poll::BoothAssignment.find(params[:id]) + if @booth_assignment.destroy notice = t("admin.booth_assignments.flash.destroy") else @@ -22,10 +22,15 @@ class Admin::Poll::BoothAssignmentsController < Admin::BaseController redirect_to admin_poll_path(@booth_assignment.poll_id, anchor: 'tab-booths'), notice: notice end + def show + @poll = ::Poll.find(params[:poll_id]) + @booth_assignment = @poll.booth_assignments.includes(:recounts, officer_assignments: [officer: [:user]]).find(params[:id]) + end + private def load_booth_assignment - @booth_assignment = ::Poll::BoothAssignment.find_by(poll: params[:poll], booth: params[:booth]) + @booth_assignment = ::Poll::BoothAssignment.find(params[:id]) end def booth_assignment_params diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 3e458428f..0c2e2797c 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -6,7 +6,7 @@ class Admin::Poll::PollsController < Admin::BaseController end def show - @poll = Poll.includes(:questions, :booths, officers: [:user]).order('poll_questions.title', 'poll_booths.name', 'users.username').find(params[:id]) + @poll = Poll.includes(:questions, booth_assignments: [:booth], officers: [:user]).order('poll_questions.title', 'poll_booths.name', 'users.username').find(params[:id]) end def new diff --git a/app/views/admin/poll/booth_assignments/show.html.erb b/app/views/admin/poll/booth_assignments/show.html.erb new file mode 100644 index 000000000..01cece32e --- /dev/null +++ b/app/views/admin/poll/booth_assignments/show.html.erb @@ -0,0 +1,73 @@ +<%= link_to admin_poll_path(@poll, anchor: 'tab-booths') do %> + + <%= @poll.name %> +<% end %> + +

    <%= @booth_assignment.booth.name %>

    + +<% if @booth_assignment.booth.location.present? %> +

    + <%= t("admin.poll_booth_assignments.show.location") %>: + <%= @booth_assignment.booth.location %> +

    +<% end %> + +
    +
      +
    • + <%= link_to t("admin.poll_booth_assignments.show.officers"), "#tab-officers" %> +
    • +
    • + <%= link_to t("admin.poll_booth_assignments.show.recounts"), "#tab-recounts" %> +
    • +
    + +
    + <% if @booth_assignment.officers.empty? %> +
    + <%= t("admin.poll_booth_assignments.show.no_officers") %> +
    + <% else %> +

    <%= t("admin.poll_booth_assignments.show.officers_list") %>

    + + + + <% @booth_assignment.officers.uniq.each do |officer| %> + + + + + <% end %> + +
    <%= link_to officer.name, admin_officer_assignments_path(officer: officer, poll: @poll) %><%= officer.email %>
    + <% end %> +
    + +
    + <% if @booth_assignment.recounts.empty? %> +
    + <%= t("admin.poll_booth_assignments.show.no_recounts") %> +
    + <% else %> +

    <%= t("admin.poll_booth_assignments.show.recounts_list") %>

    + + + + + + + + + + <% @booth_assignment.recounts.sort_by{|r| r.date}.each do |recount| %> + + + + + + <% end %> + +
    <%= t("admin.poll_booth_assignments.show.date") %><%= t("admin.poll_booth_assignments.show.count_by_officer") %><%= t("admin.poll_booth_assignments.show.count_by_system") %>
    <%= l recount.date.to_date %><%= recount.count %>0
    + <% end %> +
    +
    diff --git a/app/views/admin/poll/booths/show.html.erb b/app/views/admin/poll/booths/show.html.erb index c72fd525d..bd9355f69 100644 --- a/app/views/admin/poll/booths/show.html.erb +++ b/app/views/admin/poll/booths/show.html.erb @@ -3,92 +3,10 @@

    - Poll 3: <%= @booth.name %> + <%= @booth.name %>

    <%= t("admin.booths.show.location") %>: <%= @booth.location %>

    - -
    -
      -
    • - <%= link_to "#tab-officers" do %> - Presidentes de mesa - <% end %> -
    • -
    • - <%= link_to "#tab-count" do %> - Recuentos - <% end %> -
    • -
    - -
    -

    Lista de presidentes de mesa

    - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - -
    FechaPresidente de mesaEmail
    13/02/2016Clemente Padilla Oterouser5@consul.dev
    13/02/2016Ana Luisa Ceja Benítezuser7@consul.dev
    14/02/2016Clemente Padilla Oterouser5@consul.dev
    -
    - -
    -

    Lista de recuentos

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    FechaVotos (Presidente de mesa)Votos (Admin)
    13/02/2016320320
    14/02/2016160140
    15/02/2016226226
    -
    -
    diff --git a/app/views/admin/poll/polls/_booths.html.erb b/app/views/admin/poll/polls/_booths.html.erb index dbd5de3e1..9a70b7c63 100644 --- a/app/views/admin/poll/polls/_booths.html.erb +++ b/app/views/admin/poll/polls/_booths.html.erb @@ -1,6 +1,6 @@

    <%= t("admin.polls.show.booths_title") %>

    -<% if @poll.booths.empty? %> +<% if @poll.booth_assignments.empty? %>
    <%= t("admin.polls.show.no_booths") %>
    @@ -12,19 +12,19 @@
    <%= t("admin.polls.show.table_assignment") %>
    - <%= link_to booth.name, admin_booth_path(booth) %> + <%= link_to booth_assignment.booth.name, admin_poll_booth_assignment_path(@poll, booth_assignment) %> - <%= booth.location %> + <%= booth_assignment.booth.location %> <%= link_to t("admin.polls.show.remove_booth"), - admin_booth_assignment_path(poll: @poll, booth: booth), + admin_booth_assignment_path(booth_assignment), method: :delete, class: "button hollow alert" %>
    +
    <% @booth_assignment.officers.uniq.each do |officer| %> @@ -50,7 +50,7 @@ <% else %>

    <%= t("admin.poll_booth_assignments.show.recounts_list") %>

    -
    +
    diff --git a/spec/factories.rb b/spec/factories.rb index 9f086ab8e..ac6f76916 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -267,6 +267,10 @@ FactoryGirl.define do user end + factory :poll_officer, class: 'Poll::Officer' do + user + end + factory :poll do sequence(:name) { |n| "Poll #{n}" } @@ -307,10 +311,6 @@ FactoryGirl.define do association :booth, factory: :poll_booth end - factory :poll_officer, class: 'Poll::Officer' do - user - end - factory :poll_officer_assignment, class: 'Poll::OfficerAssignment' do association :officer, factory: :poll_officer association :booth_assignment, factory: :poll_booth_assignment diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index c7db2b593..ff2ae833c 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -36,7 +36,7 @@ feature 'Admin booths assignments' do expect(page).to have_content booth.name end - scenario 'remove booth from poll', :js do + scenario 'Remove booth from poll', :js do poll = create(:poll) booth = create(:poll_booth) assignment = create(:poll_booth_assignment, poll: poll, booth: booth) @@ -63,4 +63,50 @@ feature 'Admin booths assignments' do expect(page).to have_content 'There are no booths assigned to this poll.' expect(page).to_not have_content booth.name end + + feature 'Show' do + scenario 'Lists all assigned poll oficers' do + poll = create(:poll) + booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + officer_assignment = create(:poll_officer_assignment, booth_assignment: booth_assignment) + officer = officer_assignment.officer + + booth_assignment_2 = create(:poll_booth_assignment, poll: poll) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment_2) + officer_2 = officer_assignment_2.officer + + visit admin_poll_path(poll) + click_link 'Booths (2)' + + click_link booth.name + + click_link 'Officers' + within('#officers_list') do + expect(page).to have_content officer.name + expect(page).to_not have_content officer_2.name + end + end + + scenario 'Lists all recounts for the booth assignment' do + poll = create(:poll) + booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + recount = create(:poll_recount, booth_assignment: booth_assignment, count: 33) + + booth_assignment_2 = create(:poll_booth_assignment, poll: poll) + recount_2 = create(:poll_recount, booth_assignment: booth_assignment_2, count: 100) + + visit admin_poll_path(poll) + click_link 'Booths (2)' + + click_link booth.name + + click_link 'Recounts' + within('#recounts_list') do + expect(page).to have_content recount.count + expect(page).to_not have_content recount_2.count + end + end + end end \ No newline at end of file From d30c97c0c24e2524fc79123de9e3e76640e6f67a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 19 Jan 2017 18:04:04 +0100 Subject: [PATCH 248/523] fixes } scss --- app/assets/stylesheets/admin.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 0f168987c..71027fa75 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -60,9 +60,10 @@ body.admin { height: $line-height*2; } - .input-group input[type="text"] { - border-radius: 0; - margin-bottom: 0 !important; + .input-group input[type="text"] { + border-radius: 0; + margin-bottom: 0 !important; + } } } From 67c287dc143cc0cb253545b6bfa31104767808c0 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 20 Jan 2017 16:50:03 +0100 Subject: [PATCH 249/523] Migrates geozones from poll questions to polls --- ...4_move_geozones_from_poll_questions_to_polls.rb | 10 ++++++++++ db/schema.rb | 14 +++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20170120153244_move_geozones_from_poll_questions_to_polls.rb diff --git a/db/migrate/20170120153244_move_geozones_from_poll_questions_to_polls.rb b/db/migrate/20170120153244_move_geozones_from_poll_questions_to_polls.rb new file mode 100644 index 000000000..a2606c370 --- /dev/null +++ b/db/migrate/20170120153244_move_geozones_from_poll_questions_to_polls.rb @@ -0,0 +1,10 @@ +class MoveGeozonesFromPollQuestionsToPolls < ActiveRecord::Migration + def change + drop_table :geozones_poll_questions + + create_table :geozones_polls do |t| + t.references :geozone, index: true, foreign_key: true + t.references :poll, index: true, foreign_key: true + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 5385ef19b..56ec117e7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170114154421) do +ActiveRecord::Schema.define(version: 20170120153244) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -307,13 +307,13 @@ ActiveRecord::Schema.define(version: 20170114154421) do t.string "census_code" end - create_table "geozones_poll_questions", force: :cascade do |t| + create_table "geozones_polls", force: :cascade do |t| t.integer "geozone_id" - t.integer "question_id" + t.integer "poll_id" end - add_index "geozones_poll_questions", ["geozone_id"], name: "index_geozones_poll_questions_on_geozone_id", using: :btree - add_index "geozones_poll_questions", ["question_id"], name: "index_geozones_poll_questions_on_question_id", using: :btree + add_index "geozones_polls", ["geozone_id"], name: "index_geozones_polls_on_geozone_id", using: :btree + add_index "geozones_polls", ["poll_id"], name: "index_geozones_polls_on_poll_id", using: :btree create_table "identities", force: :cascade do |t| t.integer "user_id" @@ -768,8 +768,8 @@ ActiveRecord::Schema.define(version: 20170114154421) do add_foreign_key "annotations", "users" add_foreign_key "failed_census_calls", "users" add_foreign_key "flags", "users" - add_foreign_key "geozones_poll_questions", "geozones" - add_foreign_key "geozones_poll_questions", "poll_questions", column: "question_id" + add_foreign_key "geozones_polls", "geozones" + add_foreign_key "geozones_polls", "polls" add_foreign_key "identities", "users" add_foreign_key "locks", "users" add_foreign_key "managers", "users" From d53c867ba43b16f2bec09a86665d758b6c95a267 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 20 Jan 2017 17:45:11 +0100 Subject: [PATCH 250/523] Adds geozone_restricted to polls --- db/migrate/20170120161058_add_geozone_restricted_to_polls.rb | 5 +++++ db/schema.rb | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170120161058_add_geozone_restricted_to_polls.rb diff --git a/db/migrate/20170120161058_add_geozone_restricted_to_polls.rb b/db/migrate/20170120161058_add_geozone_restricted_to_polls.rb new file mode 100644 index 000000000..d6ed3a2c7 --- /dev/null +++ b/db/migrate/20170120161058_add_geozone_restricted_to_polls.rb @@ -0,0 +1,5 @@ +class AddGeozoneRestrictedToPolls < ActiveRecord::Migration + def change + add_column :polls, :geozone_restricted, :boolean, default: false, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 56ec117e7..fcc836f01 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170120153244) do +ActiveRecord::Schema.define(version: 20170120161058) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -459,7 +459,8 @@ ActiveRecord::Schema.define(version: 20170120153244) do t.string "name" t.datetime "starts_at" t.datetime "ends_at" - t.boolean "published", default: false + t.boolean "published", default: false + t.boolean "geozone_restricted", default: false end create_table "proposal_notifications", force: :cascade do |t| From 063c94822d090a228066720de5aab85ed6c18f9c Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 20 Jan 2017 17:47:49 +0100 Subject: [PATCH 251/523] Removes all_geozones from poll_questions table --- ...20170120164547_remove_all_geozones_from_poll_questions.rb | 5 +++++ db/schema.rb | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170120164547_remove_all_geozones_from_poll_questions.rb diff --git a/db/migrate/20170120164547_remove_all_geozones_from_poll_questions.rb b/db/migrate/20170120164547_remove_all_geozones_from_poll_questions.rb new file mode 100644 index 000000000..b4fcecd20 --- /dev/null +++ b/db/migrate/20170120164547_remove_all_geozones_from_poll_questions.rb @@ -0,0 +1,5 @@ +class RemoveAllGeozonesFromPollQuestions < ActiveRecord::Migration + def change + remove_column :poll_questions, :all_geozones, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index fcc836f01..8eb3c5ce3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170120161058) do +ActiveRecord::Schema.define(version: 20170120164547) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -424,7 +424,6 @@ ActiveRecord::Schema.define(version: 20170120161058) do t.datetime "hidden_at" t.datetime "created_at" t.datetime "updated_at" - t.boolean "all_geozones", default: false t.tsvector "tsv" end From d0245059604879bcd7684e92c54263986b81d9d4 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 20 Jan 2017 18:58:03 +0100 Subject: [PATCH 252/523] moves geozones from poll question to poll in models --- app/models/poll.rb | 10 ++++++++-- app/models/poll/question.rb | 25 ++++--------------------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 79726715e..52afaafa5 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -6,6 +6,8 @@ class Poll < ActiveRecord::Base has_many :officers, through: :officer_assignments has_many :questions + has_and_belongs_to_many :geozones + validates :name, presence: true validate :date_range @@ -14,6 +16,7 @@ class Poll < ActiveRecord::Base scope :incoming, -> { where('? < starts_at', Time.current) } scope :expired, -> { where('ends_at < ?', Time.current) } scope :published, -> { where('published = ?', true) } + scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } scope :sort_for_list, -> { order(:starts_at) } @@ -30,12 +33,15 @@ class Poll < ActiveRecord::Base end def answerable_by?(user) - user.present? && user.level_two_or_three_verified? && current? + user.present? && + user.level_two_or_three_verified? && + current? && + (!geozone_restricted || geozone_ids.include?(user.geozone_id)) end def self.answerable_by(user) return none if user.nil? || user.unverified? - current + current.joins(:geozones).where('geozone_restricted = ? or geozones.id = ?', false, user.geozone_id) end def document_has_voted?(document_number, document_type) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 9f680c739..16786a9b6 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -11,7 +11,6 @@ class Poll::Question < ActiveRecord::Base has_many :comments, as: :commentable has_many :answers has_many :partial_results - has_and_belongs_to_many :geozones belongs_to :proposal validates :title, presence: true @@ -21,9 +20,7 @@ class Poll::Question < ActiveRecord::Base validates :title, length: { in: 4..Poll::Question.title_max_length } validates :description, length: { maximum: Poll::Question.description_max_length } - scope :no_poll, -> { where(poll_id: nil) } - scope :by_poll_id, -> (poll_id) { where(poll_id: poll_id) } - scope :by_geozone_id, -> (geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } + scope :by_poll_id, ->(poll_id) { where(poll_id: poll_id) } scope :sort_for_list, -> { order('poll_questions.proposal_id IS NULL', :created_at)} scope :for_render, -> { includes(:author, :proposal) } @@ -41,9 +38,7 @@ class Poll::Question < ActiveRecord::Base summary => 'B', description => 'C', author.username => 'C', - author_visible_name => 'C', - geozones.pluck(:name).join(' ') => 'C' - } + author_visible_name => 'C' } end def description @@ -62,29 +57,17 @@ class Poll::Question < ActiveRecord::Base self.title = proposal.title self.description = proposal.description self.summary = proposal.summary - self.all_geozones = true self.valid_answers = I18n.t('poll_questions.default_valid_answers') end end def answerable_by?(user) - poll.answerable_by?(user) && (self.all_geozones || self.geozone_ids.include?(user.geozone_id)) + poll.answerable_by?(user) end def self.answerable_by(user) return none if user.nil? || user.unverified? - - where(poll_id: answerable_polls(user), - geozones: { id: answerable_geozones(user) }). - joins(:geozones) - end - - def self.answerable_polls(user) - Poll.answerable_by(user) - end - - def self.answerable_geozones(user) - user.geozone || Geozone.city + where(poll_id: Poll.answerable_by(user).pluck(:id)) end end From 8dbc72c37473cada4c7c5fecb41b977a87ae1909 Mon Sep 17 00:00:00 2001 From: kikito Date: Fri, 20 Jan 2017 18:58:19 +0100 Subject: [PATCH 253/523] moves geozones from poll question to poll in dev_seeds --- db/dev_seeds.rb | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index efdf0fa6c..066603e3c 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -466,27 +466,32 @@ end puts "Creating polls" -puts "Active Poll" -poll = Poll.create(name: "Poll 1", - starts_at: 1.month.ago, - ends_at: 1.month.from_now) -puts " #{poll.name}" +puts "Active Polls" +(1..5).each do |i| + poll = Poll.create(name: "Active Poll #{i}", + starts_at: 1.month.ago, + ends_at: 1.month.from_now, + geozone_restricted: true, + geozones: Geozone.reorder("RANDOM()").limit(3) + ) + puts " #{poll.name}" +end puts "Upcoming Poll" -poll = Poll.create(name: "Poll 2", +poll = Poll.create(name: "Upcoming Poll", starts_at: 1.month.from_now, ends_at: 2.months.from_now) puts " #{poll.name}" puts "Expired Poll" -poll = Poll.create(name: "Poll 3", +poll = Poll.create(name: "Expired Poll", starts_at: 2.months.ago, ends_at: 1.months.ago) puts " #{poll.name}" puts "Creating Poll Questions" -(1..20).each do |i| +(1..50).each do |i| poll = Poll.reorder("RANDOM()").first author = User.reorder("RANDOM()").first description = "

    #{Faker::Lorem.paragraphs.join('

    ')}

    " @@ -496,14 +501,12 @@ puts "Creating Poll Questions" summary: Faker::Lorem.sentence(3), description: description, valid_answers: Faker::Lorem.words(3).join(', '), - poll: poll, - geozones: Geozone.reorder("RANDOM()").limit(3), - all_geozones: [true, false].sample) + poll: poll) puts " #{question.title}" end puts "Creating Poll Booths" -10.times.each_with_index do |i| +30.times.each_with_index do |i| Poll::Booth.create(name: "Booth #{i}", polls: [Poll.all.sample]) end @@ -515,7 +518,7 @@ end puts "Creating Poll Officer Assignments" (1..10).to_a.sample.times do |i| Poll::BoothAssignment.all.sample(i).each do |booth_assignment| - Poll::OfficerAssignment.create(officer: poll_officer, + Poll::OfficerAssignment.create(officer: poll_officer.poll_officer, booth_assignment: booth_assignment, date: booth_assignment.poll.starts_at) end @@ -523,7 +526,7 @@ end puts "Creating Poll Question from Proposals" -(1..3).each do |i| +(1..3).each do proposal = Proposal.reorder("RANDOM()").first poll = Poll.current.first question = Poll::Question.create(valid_answers: "Yes, No") @@ -535,7 +538,7 @@ end puts "Creating Successful Proposals" -(1..10).each do |i| +(1..10).each do proposal = Proposal.reorder("RANDOM()").first poll = Poll.current.first question = Poll::Question.create(valid_answers: "Yes, No") @@ -547,11 +550,11 @@ end puts "Commenting Poll Questions" -(1..30).each do |i| +(1..30).each do author = User.reorder("RANDOM()").first question = Poll::Question.reorder("RANDOM()").first Comment.create!(user: author, created_at: rand(question.created_at .. Time.current), commentable: question, body: Faker::Lorem.sentence) -end \ No newline at end of file +end From 8bd74d2a20deddb97cd5aa0cc639a78d00cd0aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 24 Jan 2017 13:07:49 +0100 Subject: [PATCH 254/523] fixes specs namespace method defined in AdminHelper now returns X/Y instead of X::Y --- app/helpers/budgets_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 84f04139c..6b37d4e4e 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -10,7 +10,7 @@ module BudgetsHelper def namespaced_budget_investment_path(investment, options={}) case namespace - when "management::budgets" + when "management/budgets" management_budget_investment_path(investment.budget, investment, options) else budget_investment_path(investment.budget, investment, options) @@ -19,7 +19,7 @@ module BudgetsHelper def namespaced_budget_investment_vote_path(investment, options={}) case namespace - when "management::budgets" + when "management/budgets" vote_management_budget_investment_path(investment.budget, investment, options) else vote_budget_investment_path(investment.budget, investment, options) From 86b895a7af2a5932297400610cf075be98c057aa Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 17:51:18 +0100 Subject: [PATCH 255/523] Adds checkbox toggle js library --- app/assets/javascripts/application.js | 2 ++ app/assets/javascripts/checkbox_toggle.js.coffee | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 app/assets/javascripts/checkbox_toggle.js.coffee diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index fba539eeb..8b2e2674b 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -49,6 +49,7 @@ //= require fixed_bar //= require banners //= require social_share +//= require checkbox_toggle //= require custom var initialize_modules = function() { @@ -74,6 +75,7 @@ var initialize_modules = function() { App.FixedBar.initialize(); App.Banners.initialize(); App.SocialShare.initialize(); + App.CheckboxToggle.initialize(); }; $(function(){ diff --git a/app/assets/javascripts/checkbox_toggle.js.coffee b/app/assets/javascripts/checkbox_toggle.js.coffee new file mode 100644 index 000000000..096ce7e25 --- /dev/null +++ b/app/assets/javascripts/checkbox_toggle.js.coffee @@ -0,0 +1,12 @@ +App.CheckboxToggle = + + initialize: -> + $('[data-checkbox-toggle]').on 'change', -> + $this = $(this) + $target = $($this.data('checkbox-toggle')) + if $this.is(':checked') + $target.show() + else + $target.hide() + + From 65b0d279954aeb0faa848f5429a11210b5e22f84 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:06:41 +0100 Subject: [PATCH 256/523] Moves geozones from questions to polls in admin controllers --- app/controllers/admin/poll/polls_controller.rb | 9 +++++++-- app/controllers/admin/poll/questions_controller.rb | 10 ++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 0c2e2797c..5895a10bf 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -1,6 +1,8 @@ class Admin::Poll::PollsController < Admin::BaseController load_and_authorize_resource + before_action :load_search, only: [:search_booths, :search_questions, :search_officers] + before_action :load_geozones, only: [:new, :create, :edit, :update] def index end @@ -78,9 +80,12 @@ class Admin::Poll::PollsController < Admin::BaseController end private + def load_geozones + @geozones = Geozone.all.order(:name) + end def poll_params - params.require(:poll).permit(:name, :starts_at, :ends_at) + params.require(:poll).permit(:name, :starts_at, :ends_at, :geozone_restricted, geozone_ids: []) end def search_params @@ -91,4 +96,4 @@ class Admin::Poll::PollsController < Admin::BaseController @search = search_params[:search] end -end \ No newline at end of file +end diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index b7b16e379..e257d8821 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -2,8 +2,6 @@ class Admin::Poll::QuestionsController < Admin::BaseController load_and_authorize_resource :poll load_and_authorize_resource :question, class: 'Poll::Question' - before_action :load_geozones, only: [:new, :create, :edit, :update] - def index @polls = Poll.all @search = search_params[:search] @@ -55,16 +53,12 @@ class Admin::Poll::QuestionsController < Admin::BaseController private - def load_geozones - @geozones = Geozone.all.order(:name) - end - def question_params - params.require(:poll_question).permit(:title, :question, :summary, :description, :proposal_id, :valid_answers, :poll_id, :geozone_ids => []) + params.require(:poll_question).permit(:title, :question, :summary, :description, :proposal_id, :valid_answers) end def search_params params.permit(:poll_id, :search) end -end \ No newline at end of file +end From 176a190149cfdd4beb704bfdbf23b91094af4680 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:08:15 +0100 Subject: [PATCH 257/523] Moves geozones from questions to polls in admin forms --- app/views/admin/poll/polls/_form.html.erb | 28 +++++++++++++------ app/views/admin/poll/questions/_form.html.erb | 13 +-------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 8de8af670..0b99ea9f5 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -1,34 +1,46 @@ <%= form_for [:admin, @poll] do |f| %>
    - <%= f.text_field :name, - placeholder: t('admin.polls.form.name'), - label: t("admin.polls.form.name") %> + <%= f.text_field :name %>
    - <%= f.label :starts_at, t("admin.polls.form.starts_at") %> <%= f.text_field :starts_at, - label: false, value: @poll.starts_at.present? ? l(@poll.starts_at.to_date) : nil, class: "js-calendar-full" %>
    - <%= f.label :ends_at, t("admin.polls.form.ends_at") %> <%= f.text_field :ends_at, - label: false, value: @poll.ends_at.present? ? l(@poll.ends_at.to_date) : nil, class: "js-calendar-full" %>
    +
    +
    + <%= f.check_box :geozone_restricted, data: { checkbox_toggle: "#geozones" } %> +
    +
    + +
    +
    + <%= f.collection_check_boxes(:geozone_ids, @geozones, :id, :name) do |b| %> +
    + <%= b.label do %> + <%= b.check_box + b.text %> + <% end %> +
    + <% end %> +
    +
    +
    <%= f.submit t("admin.polls.#{admin_submit_action(@poll)}.submit_button"), class: "button success expanded" %>
    -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/admin/poll/questions/_form.html.erb b/app/views/admin/poll/questions/_form.html.erb index dbc8883e3..e5c228b4e 100644 --- a/app/views/admin/poll/questions/_form.html.erb +++ b/app/views/admin/poll/questions/_form.html.erb @@ -29,17 +29,6 @@ ckeditor: { language: I18n.locale } %> -
    - <%= f.collection_check_boxes(:geozone_ids, @geozones, :id, :name) do |b| %> -
    - <%= b.label do %> - <%= b.check_box + b.text %> - <% end %> -
    - <% end %> -
    - <%# TODO include all link %> -
    <%= f.submit(class: "button expanded", value: t("shared.save")) %> @@ -48,4 +37,4 @@
    -<% end %> \ No newline at end of file +<% end %> From ab63c18d01d8d5b2704698636b26f430bb8530a6 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:08:48 +0100 Subject: [PATCH 258/523] Moves geozones from questions to polls in admin show views --- app/views/admin/poll/polls/show.html.erb | 12 +++++++++--- app/views/admin/poll/questions/show.html.erb | 9 --------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/views/admin/poll/polls/show.html.erb b/app/views/admin/poll/polls/show.html.erb index fdc00b949..363d14630 100644 --- a/app/views/admin/poll/polls/show.html.erb +++ b/app/views/admin/poll/polls/show.html.erb @@ -6,9 +6,15 @@ <%= @poll.name %>
    -

    + (<%= l @poll.starts_at.to_date %> - <%= l @poll.ends_at.to_date %>) -

    + +<% if @poll.geozone_restricted %> +  •  + + <%= @poll.geozones.pluck(:name).to_sentence %> + +<% end %>
    <%= render "filter_subnav" %> @@ -27,4 +33,4 @@ <%= render "search_officers" %> <%= render 'officers' %>
    - \ No newline at end of file + diff --git a/app/views/admin/poll/questions/show.html.erb b/app/views/admin/poll/questions/show.html.erb index 91bf398af..72109693b 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -46,15 +46,6 @@ <%= @question.description %>

    -

    - <%= t("admin.questions.show.geozones") %> -
    - <% @question.geozones.each do |geozone| %> - - <%= geozone.name %> - - <% end %> -

    <%= link_to t("admin.questions.show.preview"), question_path(@question) %> From 6711063c7d8069562a690129efbd8cc8e1f129c5 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:09:27 +0100 Subject: [PATCH 259/523] Moves geozones from question to poll in user show views --- app/views/polls/questions/show.html.erb | 6 ------ app/views/polls/show.html.erb | 5 +++++ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/views/polls/questions/show.html.erb b/app/views/polls/questions/show.html.erb index 91dcff01d..04d4a3372 100644 --- a/app/views/polls/questions/show.html.erb +++ b/app/views/polls/questions/show.html.erb @@ -14,12 +14,6 @@ <% end %>

    <%= @question.summary %>

    - -
      - <% @question.geozones.each do |g| %> -
    • <%= g.name %>
    • - <% end %> -
    diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index fb207618d..5270e746d 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -11,6 +11,11 @@ <%= t("polls.show.question_count_html", count: @poll.questions.count) %>

    +
      + <% @poll.geozones.each do |g| %> +
    • <%= g.name %>
    • + <% end %> +
    <%= render "callout" %>
    From ddf8d5f811d608d87ea7f0d35a4b58d4797ab638 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:10:13 +0100 Subject: [PATCH 260/523] Removes answerable/non_answerable questions in polls Now they are either all answerable or non-answerable, so it is not worth it to make the distinction in code --- app/controllers/polls_controller.rb | 3 +-- app/views/polls/show.html.erb | 16 +--------------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index 9c83bc3e3..a93c84e9d 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -9,8 +9,7 @@ class PollsController < ApplicationController end def show - @answerable_questions = @poll.questions.answerable_by(current_user).for_render.sort_for_list - @non_answerable_questions = @poll.questions.where.not(id: @answerable_questions.map(&:id)).for_render.sort_for_list + @questions = @poll.questions.for_render.sort_for_list @answers_by_question_id = {} poll_partial_results = Poll::PartialResult.by_question(@poll.question_ids).by_author(current_user.try(:id)) diff --git a/app/views/polls/show.html.erb b/app/views/polls/show.html.erb index 5270e746d..c5613e580 100644 --- a/app/views/polls/show.html.erb +++ b/app/views/polls/show.html.erb @@ -35,21 +35,7 @@
    - <% @answerable_questions.each do |question| %> - <%= render 'polls/questions/question', question: question %> - <% end %> - - <% if can?(:answer, @poll) && - @non_answerable_questions.present? %> -
    -

    - <%= t("polls.show.cant_answer_wrong_geozone", - count: @non_answerable_questions.count) %> -

    -
    - <% end %> - - <% @non_answerable_questions.each do |question| %> + <% @questions.each do |question| %> <%= render 'polls/questions/question', question: question %> <% end %>
    From 6ed73f34b6d8706d50bbd09b88d22c3f843bd86c Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:10:30 +0100 Subject: [PATCH 261/523] Adds activerecord translations --- config/locales/activerecord.es.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index bdaeec551..644207b86 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -100,6 +100,11 @@ es: external_url: "Enlace a documentación adicional" geozone_id: "Ámbito de actuación" title: "Título" + poll: + name: "Nombre" + starts_at: "Fecha de apertura" + ends_at: "Fecha de cierre" + geozone_restricted: "Restringida por zonas" poll/question: title: "Pregunta" valid_answers: "Posibles respuestas" From 15b531f06870dcc3cd84bf9b2b8ea9b04548adfb Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 18:10:41 +0100 Subject: [PATCH 262/523] Fixes failing specs --- spec/features/admin/poll/questions_spec.rb | 7 ++-- spec/features/polls/polls_spec.rb | 42 +++++++++++++--------- spec/features/polls/questions_spec.rb | 18 +++++----- spec/models/abilities/common_spec.rb | 25 ++++++++----- spec/models/poll/question_spec.rb | 1 - 5 files changed, 54 insertions(+), 39 deletions(-) diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb index 90e55107c..a5e155848 100644 --- a/spec/features/admin/poll/questions_spec.rb +++ b/spec/features/admin/poll/questions_spec.rb @@ -18,7 +18,8 @@ feature 'Admin poll questions' do scenario 'Show' do geozone = create(:geozone) - question = create(:poll_question, geozone_ids: geozone.id) + poll = create(:poll, geozone_restricted: true, geozone_ids: [geozone.id]) + question = create(:poll_question, poll: poll) visit admin_question_path(question) @@ -27,7 +28,6 @@ feature 'Admin poll questions' do expect(page).to have_content(question.summary) expect(page).to have_content(question.author.name) expect(page).to have_content(question.valid_answers.join(" ")) - expect(page).to have_content(geozone.name) end scenario 'Create' do @@ -53,7 +53,6 @@ feature 'Admin poll questions' do end scenario 'Create from successful proposal index' do - geozones = create_list(:geozone, 3) proposal = create(:proposal, :successful) visit proposals_path @@ -115,4 +114,4 @@ feature 'Admin poll questions' do pending "Mark all city by default when creating a poll question from a successful proposal" -end \ No newline at end of file +end diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index df8ee5105..c4a8f55a2 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -82,7 +82,9 @@ feature 'Polls' do end scenario 'Level 1 users' do - create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + poll.update(geozone_restricted: true) + poll.geozones << geozone + create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') login_as(create(:user, geozone: geozone)) visit poll_path(poll) @@ -96,8 +98,9 @@ feature 'Polls' do end scenario 'Level 2 users in an incoming poll' do - incoming_poll = create(:poll, :incoming) - create(:poll_question, poll: incoming_poll, geozone_ids: [geozone.id], valid_answers: 'Rey, Finn') + incoming_poll = create(:poll, :incoming, geozone_restricted: true) + incoming_poll.geozones << geozone + create(:poll_question, poll: incoming_poll, valid_answers: 'Rey, Finn') login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(incoming_poll) @@ -111,8 +114,9 @@ feature 'Polls' do end scenario 'Level 2 users in an expired poll' do - expired_poll = create(:poll, :expired) - create(:poll_question, poll: expired_poll, geozone_ids: [geozone.id], valid_answers: 'Luke, Leia') + expired_poll = create(:poll, :expired, geozone_restricted: true) + expired_poll.geozones << geozone + create(:poll_question, poll: expired_poll, valid_answers: 'Luke, Leia') login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(expired_poll) @@ -126,21 +130,23 @@ feature 'Polls' do end scenario 'Level 2 users in a poll with questions for a geozone which is not theirs' do - create(:poll_question, poll: poll, geozone_ids: [], valid_answers: 'Vader, Palpatine') + poll.update(geozone_restricted: true) + poll.geozones << create(:geozone) + create(:poll_question, poll: poll, valid_answers: 'Vader, Palpatine') login_as(create(:user, :level_two)) visit poll_path(poll) - expect(page).to have_content("You can't answers the following 1 questions because are not available in your geozone.") - expect(page).to have_content('Vader') expect(page).to have_content('Palpatine') expect(page).to_not have_link('Vader') expect(page).to_not have_link('Palpatine') end - scenario 'Level 2 users reading a same-geozone question' do - create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + scenario 'Level 2 users reading a same-geozone poll' do + poll.update(geozone_restricted: true) + poll.geozones << geozone + create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') login_as(create(:user, :level_two, geozone: geozone)) visit poll_path(poll) @@ -148,9 +154,9 @@ feature 'Polls' do expect(page).to have_link('Chewbacca') end - scenario 'Level 2 users reading a all-geozones question' do - create(:poll_question, poll: poll, all_geozones: true, valid_answers: 'Han Solo, Chewbacca') - login_as(create(:user, :level_two, geozone: geozone)) + scenario 'Level 2 users reading a all-geozones poll' do + create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + login_as(create(:user, :level_two)) visit poll_path(poll) expect(page).to have_link('Han Solo') @@ -158,8 +164,8 @@ feature 'Polls' do end scenario 'Level 2 users who have already answered' do - question = create(:poll_question, poll: poll, geozone_ids:[geozone.id], valid_answers: 'Han Solo, Chewbacca') - user = create(:user, :level_two, geozone: geozone) + question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + user = create(:user, :level_two) create(:poll_partial_result, question: question, author: user, answer: 'Chewbacca') login_as user @@ -171,7 +177,9 @@ feature 'Polls' do end scenario 'Level 2 users answering', :js do - create(:poll_question, poll: poll, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + poll.update(geozone_restricted: true) + poll.geozones << geozone + create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) login_as user visit poll_path(poll) @@ -183,4 +191,4 @@ feature 'Polls' do end end -end \ No newline at end of file +end diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index 8e6574c5f..af4c1058c 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -14,7 +14,7 @@ feature 'Poll Questions' do context 'Answering' do let(:geozone) { create(:geozone) } - + let(:poll) { create(:poll, geozone_restricted: true, geozone_ids: [geozone.id]) } scenario 'Non-logged in users' do question = create(:poll_question, valid_answers: 'Han Solo, Chewbacca') @@ -29,7 +29,7 @@ feature 'Poll Questions' do end scenario 'Level 1 users' do - question = create(:poll_question, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') login_as(create(:user, geozone: geozone)) visit question_path(question) @@ -43,9 +43,11 @@ feature 'Poll Questions' do end scenario 'Level 2 users in an poll question for a geozone which is not theirs' do - question = create(:poll_question, geozone_ids: [], valid_answers: 'Vader, Palpatine') - login_as(create(:user, :level_two)) + other_poll = create(:poll, geozone_restricted: true, geozone_ids: [create(:geozone).id]) + question = create(:poll_question, poll: other_poll, valid_answers: 'Vader, Palpatine') + + login_as(create(:user, :level_two, geozone: geozone)) visit question_path(question) expect(page).to have_content('Vader') @@ -55,7 +57,7 @@ feature 'Poll Questions' do end scenario 'Level 2 users who can answer' do - question = create(:poll_question, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') login_as(create(:user, :level_two, geozone: geozone)) visit question_path(question) @@ -65,7 +67,7 @@ feature 'Poll Questions' do end scenario 'Level 2 users who have already answered' do - question = create(:poll_question, geozone_ids:[geozone.id], valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) create(:poll_partial_result, question: question, author: user, answer: 'Chewbacca') @@ -79,7 +81,7 @@ feature 'Poll Questions' do end scenario 'Level 2 users answering', :js do - question = create(:poll_question, geozone_ids: [geozone.id], valid_answers: 'Han Solo, Chewbacca') + question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) login_as user @@ -92,4 +94,4 @@ feature 'Poll Questions' do end end -end \ No newline at end of file +end diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index ff4fd315e..d1eddcd51 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -27,19 +27,26 @@ describe "Abilities::Common" do let(:current_poll) { create(:poll) } let(:incoming_poll) { create(:poll, :incoming) } + let(:incoming_poll_from_own_geozone) { create(:poll, :incoming, geozone_restricted: true, geozones: [geozone]) } + let(:incoming_poll_from_other_geozone) { create(:poll, :incoming, geozone_restricted: true, geozones: [create(:geozone)]) } let(:expired_poll) { create(:poll, :expired) } + let(:expired_poll_from_own_geozone) { create(:poll, :expired, geozone_restricted: true, geozones: [geozone]) } + let(:expired_poll_from_other_geozone) { create(:poll, :expired, geozone_restricted: true, geozones: [create(:geozone)]) } + let(:poll) { create(:poll, geozone_restricted: false) } + let(:poll_from_own_geozone) { create(:poll, geozone_restricted: true, geozones: [geozone]) } + let(:poll_from_other_geozone) { create(:poll, geozone_restricted: true, geozones: [create(:geozone)]) } - let(:poll_question_from_own_geozone) { create(:poll_question, geozones: [geozone]) } - let(:poll_question_from_other_geozone) { create(:poll_question, geozones: [create(:geozone)]) } - let(:poll_question_from_all_geozones) { create(:poll_question, all_geozones: true) } + let(:poll_question_from_own_geozone) { create(:poll_question, poll: poll_from_own_geozone) } + let(:poll_question_from_other_geozone) { create(:poll_question, poll: poll_from_other_geozone) } + let(:poll_question_from_all_geozones) { create(:poll_question, poll: poll) } - let(:expired_poll_question_from_own_geozone) { create(:poll_question, poll: expired_poll, geozones: [geozone]) } - let(:expired_poll_question_from_other_geozone) { create(:poll_question, poll: expired_poll, geozones: [create(:geozone)]) } - let(:expired_poll_question_from_all_geozones) { create(:poll_question, poll: expired_poll, all_geozones: true) } + let(:expired_poll_question_from_own_geozone) { create(:poll_question, poll: expired_poll_from_own_geozone) } + let(:expired_poll_question_from_other_geozone) { create(:poll_question, poll: expired_poll_from_other_geozone) } + let(:expired_poll_question_from_all_geozones) { create(:poll_question, poll: expired_poll) } - let(:incoming_poll_question_from_own_geozone) { create(:poll_question, poll: incoming_poll, geozones: [geozone]) } - let(:incoming_poll_question_from_other_geozone) { create(:poll_question, poll: incoming_poll, geozones: [create(:geozone)]) } - let(:incoming_poll_question_from_all_geozones) { create(:poll_question, poll: incoming_poll, all_geozones: true) } + let(:incoming_poll_question_from_own_geozone) { create(:poll_question, poll: incoming_poll_from_own_geozone) } + let(:incoming_poll_question_from_other_geozone) { create(:poll_question, poll: incoming_poll_from_other_geozone) } + let(:incoming_poll_question_from_all_geozones) { create(:poll_question, poll: incoming_poll) } it { should be_able_to(:index, Debate) } it { should be_able_to(:show, debate) } diff --git a/spec/models/poll/question_spec.rb b/spec/models/poll/question_spec.rb index fa572467a..057dfebca 100644 --- a/spec/models/poll/question_spec.rb +++ b/spec/models/poll/question_spec.rb @@ -20,7 +20,6 @@ RSpec.describe Poll::Question, type: :model do expect(q.author_visible_name).to eq(p.author.name) expect(q.proposal_id).to eq(p.id) expect(q.title).to eq(p.title) - expect(q.all_geozones).to be true end end From e935629fdb3c768fa7b06270cf8cdbf42ca15b7d Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 24 Jan 2017 19:01:28 +0100 Subject: [PATCH 263/523] i18n --- config/locales/admin.en.yml | 5 ----- config/locales/admin.es.yml | 5 ----- config/locales/en.yml | 1 - config/locales/es.yml | 1 - 4 files changed, 12 deletions(-) diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index c61a75bf1..3d0d324fa 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -301,10 +301,6 @@ en: edit: title: "Edit poll" submit_button: "Update poll" - form: - name: "Name" - starts_at: "Open date" - ends_at: "Close date" show: questions_tab: Questions booths_tab: Booths @@ -357,7 +353,6 @@ en: valid_answers: Valid answers summary: Summary description: Description - geozones: Geozones preview: View on website booths: index: diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 8efda5869..cca26a737 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -301,10 +301,6 @@ es: edit: title: "Editar votación" submit_button: "Actualizar votación" - form: - name: "Nombre" - starts_at: "Fecha de apertura" - ends_at: "Fecha de cierre" show: questions_tab: Preguntas booths_tab: Urnas @@ -357,7 +353,6 @@ es: valid_answers: Respuestas válidas summary: Resumen description: Descripción - geozones: Distritos preview: Ver en la web booths: index: diff --git a/config/locales/en.yml b/config/locales/en.yml index 1fe8ea956..2697fb396 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -411,7 +411,6 @@ en: verify_link: "verify your account" cant_answer_incoming: "This poll has not yet started." cant_answer_expired: "This poll has finished." - cant_answer_wrong_geozone: "You can't answers the following %{count} questions because are not available in your geozone." question_count_html: "This poll has a total of %{count} qeustions." poll_questions: create_question: "Create question" diff --git a/config/locales/es.yml b/config/locales/es.yml index 5b42d0bd3..2ae41a5ce 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -411,7 +411,6 @@ es: verify_link: "verifica tu cuenta" cant_answer_incoming: "Esta votación todavía no ha comenzado." cant_answer_expired: "Esta votación ha terminado." - cant_answer_wrong_geozone: "No puedes responder a las siguientes %{count} preguntas porque no están disponibles en tu zona:" question_count_html: "Esta votación tiene un total de %{count} preguntas." poll_questions: create_question: "Crear pregunta para votación" From 25930563e9e57fb3a55c67b7b87162e71b1ee09f Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 25 Jan 2017 10:15:38 +0100 Subject: [PATCH 264/523] adds missing i18n --- config/locales/activerecord.en.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 7676cf394..302b6767a 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -105,6 +105,11 @@ en: external_url: "Link to additional documentation" geozone_id: "Scope of operation" title: "Title" + poll: + name: "Name" + starts_at: "Start Date" + ends_at: "Closing Date" + geozone_restricted: "Restricted by geozone" poll/question: title: "Question" valid_answers: "Posibles answers" From 2be88cb316c94906c9f96e2d521700ff21e181f2 Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 25 Jan 2017 10:46:57 +0100 Subject: [PATCH 265/523] Adds missing validation to poll::question. Fixes specs --- app/controllers/admin/poll/questions_controller.rb | 2 +- app/models/poll/question.rb | 1 + spec/features/admin/poll/questions_spec.rb | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index e257d8821..a9a1d0c76 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -54,7 +54,7 @@ class Admin::Poll::QuestionsController < Admin::BaseController private def question_params - params.require(:poll_question).permit(:title, :question, :summary, :description, :proposal_id, :valid_answers) + params.require(:poll_question).permit(:poll_id, :title, :question, :summary, :description, :proposal_id, :valid_answers) end def search_params diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 16786a9b6..7d3da1b00 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -13,6 +13,7 @@ class Poll::Question < ActiveRecord::Base has_many :partial_results belongs_to :proposal + validates :poll_id, presence: true validates :title, presence: true validates :summary, presence: true validates :author, presence: true diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb index a5e155848..de26889d6 100644 --- a/spec/features/admin/poll/questions_spec.rb +++ b/spec/features/admin/poll/questions_spec.rb @@ -31,6 +31,7 @@ feature 'Admin poll questions' do end scenario 'Create' do + poll = create(:poll, name: 'Movies') title = "Star Wars: Episode IV - A New Hope" summary = "It is a period of civil war. Rebel spaceships, striking from a hidden base, have won their first victory against the evil Galactic Empire" description = %{ @@ -41,6 +42,7 @@ feature 'Admin poll questions' do visit admin_questions_path click_link "Create question" + select 'Movies', from: 'poll_question_poll_id' fill_in 'poll_question_title', with: title fill_in 'poll_question_summary', with: summary fill_in 'poll_question_description', with: description @@ -53,6 +55,7 @@ feature 'Admin poll questions' do end scenario 'Create from successful proposal index' do + poll = create(:poll, name: 'Proposals') proposal = create(:proposal, :successful) visit proposals_path @@ -64,6 +67,8 @@ feature 'Admin poll questions' do expect(page).to have_field('poll_question_description', with: proposal.description) expect(page).to have_field('poll_question_valid_answers', with: "Yes, No") + select 'Proposals', from: 'poll_question_poll_id' + click_button 'Save' expect(page).to have_content(proposal.title) From 499f9b51e23cee95a50da556e4f285e06533e16e Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 25 Jan 2017 11:19:18 +0100 Subject: [PATCH 266/523] makes it possible to create orphan poll questions --- app/models/poll/question.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 7d3da1b00..16786a9b6 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -13,7 +13,6 @@ class Poll::Question < ActiveRecord::Base has_many :partial_results belongs_to :proposal - validates :poll_id, presence: true validates :title, presence: true validates :summary, presence: true validates :author, presence: true From 900563e31c8d73e61a94273998a032c399c7f5c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 12:03:48 +0100 Subject: [PATCH 267/523] adds poll_id and stats fields to poll_voters --- app/models/poll/voter.rb | 4 +++- ...542_add_poll_id_and_stats_fields_to_poll_voter.rb | 12 ++++++++++++ db/schema.rb | 8 ++++++-- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20170125104542_add_poll_id_and_stats_fields_to_poll_voter.rb diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 8b0202aee..dd8c85d8f 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,11 +1,13 @@ class Poll class Voter < ActiveRecord::Base belongs_to :booth_assignment - delegate :poll, to: :booth_assignment + belongs_to :poll validates :booth_assignment, presence: true validate :in_census validate :has_not_voted + validates :poll, presence: true + validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type] } def in_census errors.add(:document_number, :not_in_census) unless census_api_response.valid? diff --git a/db/migrate/20170125104542_add_poll_id_and_stats_fields_to_poll_voter.rb b/db/migrate/20170125104542_add_poll_id_and_stats_fields_to_poll_voter.rb new file mode 100644 index 000000000..84e7de5d9 --- /dev/null +++ b/db/migrate/20170125104542_add_poll_id_and_stats_fields_to_poll_voter.rb @@ -0,0 +1,12 @@ +class AddPollIdAndStatsFieldsToPollVoter < ActiveRecord::Migration + def change + add_column :poll_voters, :poll_id, :integer, null: false + + remove_column :poll_voters, :booth_assignment_id, :integer, null: false + add_column :poll_voters, :booth_assignment_id, :integer + + add_column :poll_voters, :age, :integer + add_column :poll_voters, :gender, :string + add_column :poll_voters, :geozone_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 8eb3c5ce3..0cdbcad2b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170120164547) do +ActiveRecord::Schema.define(version: 20170125104542) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -449,9 +449,13 @@ ActiveRecord::Schema.define(version: 20170120164547) do create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type" - t.integer "booth_assignment_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "poll_id", null: false + t.integer "booth_assignment_id" + t.integer "age" + t.string "gender" + t.integer "geozone_id" end create_table "polls", force: :cascade do |t| From 8f235c25d30895c330e568a3922b0486ff59292f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 12:18:15 +0100 Subject: [PATCH 268/523] poll has_many voters --- app/models/poll.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 52afaafa5..c5da9dcd0 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,7 +1,7 @@ class Poll < ActiveRecord::Base has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :booths, through: :booth_assignments - has_many :voters, through: :booth_assignments + has_many :voters has_many :officer_assignments, through: :booth_assignments has_many :officers, through: :officer_assignments has_many :questions From 6bc4f5b3074719509d8dcb27041a478932d1b839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 12:46:44 +0100 Subject: [PATCH 269/523] adds Poll::Answer model for web users PartialResults is kept for booth results --- app/controllers/polls/questions_controller.rb | 12 +++++------- app/controllers/polls_controller.rb | 8 ++++---- app/models/poll/answer.rb | 13 +++++++++++++ db/migrate/20170125112017_create_poll_answers.rb | 15 +++++++++++++++ db/schema.rb | 14 +++++++++++++- spec/factories.rb | 6 ++++++ spec/features/polls/polls_spec.rb | 2 +- spec/features/polls/questions_spec.rb | 2 +- 8 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 app/models/poll/answer.rb create mode 100644 db/migrate/20170125112017_create_poll_answers.rb diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index 03e71c15b..e9c7e2bbd 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -1,7 +1,7 @@ class Polls::QuestionsController < ApplicationController load_and_authorize_resource :poll - load_and_authorize_resource :question, class: 'Poll::Question'#, through: :poll + load_and_authorize_resource :question, class: 'Poll::Question' has_orders %w{most_voted newest oldest}, only: :show @@ -10,17 +10,15 @@ class Polls::QuestionsController < ApplicationController @comment_tree = CommentTree.new(@commentable, params[:page], @current_order) set_comment_flags(@comment_tree.comments) - question_answer = @question.partial_results.where(author_id: current_user.try(:id)).first + question_answer = @question.answers.where(author_id: current_user.try(:id)).first @answers_by_question_id = {@question.id => question_answer.try(:answer)} end def answer - partial_result = @question.partial_results.find_or_initialize_by(author: current_user, - amount: 1, - origin: 'web') + answer = @question.answers.find_or_initialize_by(author: current_user) - partial_result.answer = params[:answer] - partial_result.save! + answer.answer = params[:answer] + answer.save! @answers_by_question_id = {@question.id => params[:answer]} end diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index a93c84e9d..ce80f8dcc 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -9,12 +9,12 @@ class PollsController < ApplicationController end def show - @questions = @poll.questions.for_render.sort_for_list + @questions = @poll.questions.for_render.sort_for_list @answers_by_question_id = {} - poll_partial_results = Poll::PartialResult.by_question(@poll.question_ids).by_author(current_user.try(:id)) - poll_partial_results.each do |result| - @answers_by_question_id[result.question_id] = result.answer + poll_answers = Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id)) + poll_answers.each do |answer| + @answers_by_question_id[answer.question_id] = answer.answer end end diff --git a/app/models/poll/answer.rb b/app/models/poll/answer.rb new file mode 100644 index 000000000..b0f2d4410 --- /dev/null +++ b/app/models/poll/answer.rb @@ -0,0 +1,13 @@ +class Poll::Answer < ActiveRecord::Base + + belongs_to :question, -> { with_hidden } + belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' + + validates :question, presence: true + validates :author, presence: true + validates :answer, presence: true + validates :answer, inclusion: {in: ->(a) { a.question.valid_answers }} + + scope :by_author, -> (author_id) { where(author_id: author_id) } + scope :by_question, -> (question_id) { where(question_id: question_id) } +end \ No newline at end of file diff --git a/db/migrate/20170125112017_create_poll_answers.rb b/db/migrate/20170125112017_create_poll_answers.rb new file mode 100644 index 000000000..7ea930d0c --- /dev/null +++ b/db/migrate/20170125112017_create_poll_answers.rb @@ -0,0 +1,15 @@ +class CreatePollAnswers < ActiveRecord::Migration + def change + create_table :poll_answers do |t| + t.integer :question_id + t.integer :author_id + t.string :answer + + t.timestamps + end + + add_index :poll_answers, :question_id + add_index :poll_answers, :author_id + add_index :poll_answers, [:question_id, :answer] + end +end diff --git a/db/schema.rb b/db/schema.rb index 0cdbcad2b..932d4e28a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170125104542) do +ActiveRecord::Schema.define(version: 20170125112017) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -374,6 +374,18 @@ ActiveRecord::Schema.define(version: 20170125104542) do add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree + create_table "poll_answers", force: :cascade do |t| + t.integer "question_id" + t.integer "author_id" + t.string "answer" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "poll_answers", ["author_id"], name: "index_poll_answers_on_author_id", using: :btree + add_index "poll_answers", ["question_id", "answer"], name: "index_poll_answers_on_question_id_and_answer", using: :btree + add_index "poll_answers", ["question_id"], name: "index_poll_answers_on_question_id", using: :btree + create_table "poll_booth_assignments", force: :cascade do |t| t.integer "booth_id" t.integer "poll_id" diff --git a/spec/factories.rb b/spec/factories.rb index f46362e16..c3e694025 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -434,6 +434,12 @@ FactoryGirl.define do end end + factory :poll_answer, class: 'Poll::Answer' do + association :question, factory: :poll_question + association :author, factory: :user + answer { question.verified_answers.sample } + end + factory :poll_partial_result, class: 'Poll::PartialResult' do association :question, factory: :poll_question association :author, factory: :user diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index c4a8f55a2..fe5957181 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -166,7 +166,7 @@ feature 'Polls' do scenario 'Level 2 users who have already answered' do question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two) - create(:poll_partial_result, question: question, author: user, answer: 'Chewbacca') + create(:poll_answer, question: question, author: user, answer: 'Chewbacca') login_as user visit poll_path(poll) diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index af4c1058c..e925c8fd6 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -70,7 +70,7 @@ feature 'Poll Questions' do question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') user = create(:user, :level_two, geozone: geozone) - create(:poll_partial_result, question: question, author: user, answer: 'Chewbacca') + create(:poll_answer, question: question, author: user, answer: 'Chewbacca') login_as user visit question_path(question) From 5806d86e336d7d6b0678553a9ed9c6b9124e0928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 12:57:00 +0100 Subject: [PATCH 270/523] changes poll_voters to optionally reference an answer adds indexes for poll_voters --- .../20170125114952_add_answer_id_to_poll_voters.rb | 9 +++++++++ db/schema.rb | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20170125114952_add_answer_id_to_poll_voters.rb diff --git a/db/migrate/20170125114952_add_answer_id_to_poll_voters.rb b/db/migrate/20170125114952_add_answer_id_to_poll_voters.rb new file mode 100644 index 000000000..34d5bbc54 --- /dev/null +++ b/db/migrate/20170125114952_add_answer_id_to_poll_voters.rb @@ -0,0 +1,9 @@ +class AddAnswerIdToPollVoters < ActiveRecord::Migration + def change + add_column :poll_voters, :answer_id, :integer, default: nil + + add_index :poll_voters, :document_number + add_index :poll_voters, :poll_id + add_index :poll_voters, [:poll_id, :document_number, :document_type], name: 'doc_by_poll' + end +end diff --git a/db/schema.rb b/db/schema.rb index 932d4e28a..290703e9e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170125112017) do +ActiveRecord::Schema.define(version: 20170125114952) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -468,8 +468,13 @@ ActiveRecord::Schema.define(version: 20170125112017) do t.integer "age" t.string "gender" t.integer "geozone_id" + t.integer "answer_id" end + add_index "poll_voters", ["document_number"], name: "index_poll_voters_on_document_number", using: :btree + add_index "poll_voters", ["poll_id", "document_number", "document_type"], name: "doc_by_poll", using: :btree + add_index "poll_voters", ["poll_id"], name: "index_poll_voters_on_poll_id", using: :btree + create_table "polls", force: :cascade do |t| t.string "name" t.datetime "starts_at" From 8d8d822323e896e0c14320740e0a96bf32f0b231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 13:04:26 +0100 Subject: [PATCH 271/523] adds answer spec --- spec/models/poll/answer_spec.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 spec/models/poll/answer_spec.rb diff --git a/spec/models/poll/answer_spec.rb b/spec/models/poll/answer_spec.rb new file mode 100644 index 000000000..73707ad80 --- /dev/null +++ b/spec/models/poll/answer_spec.rb @@ -0,0 +1,16 @@ +require 'rails_helper' + +describe Poll::Answer do + + describe "validations" do + it "validates that the answers are included in the Poll::Question's list" do + q = create(:poll_question, valid_answers: 'One, Two, Three') + expect(build(:poll_answer, question: q, answer: 'One')).to be_valid + expect(build(:poll_answer, question: q, answer: 'Two')).to be_valid + expect(build(:poll_answer, question: q, answer: 'Three')).to be_valid + + expect(build(:poll_answer, question: q, answer: 'Four')).to_not be_valid + end + end + +end From 0b2454fb97eebdb88ef3e2d3807a255e47d251cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 14:17:49 +0100 Subject: [PATCH 272/523] adds User#age --- app/models/user.rb | 8 ++++++++ spec/models/user_spec.rb | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/app/models/user.rb b/app/models/user.rb index 8e41a0427..80b0cb621 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -246,6 +246,14 @@ class User < ActiveRecord::Base "#{name} (#{email})" end + def age + if date_of_birth.blank? + nil + else + ((Date.today - date_of_birth.to_date).to_i / 365.25).to_i + end + end + def save_requiring_finish_signup begin self.registering_with_oauth = true diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 0f03086ba..789341fe9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -65,6 +65,13 @@ describe User do end end + describe "#age" do + it "is the rounded integer age based on the date_of_birth" do + user = create(:user, date_of_birth: 33.years.ago) + expect(user.age).to eq(33) + end + end + describe 'preferences' do describe 'email_on_comment' do it 'should be false by default' do From 5a72e4fbe8f30b56d57d08cc742cea84ae021b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 14:18:32 +0100 Subject: [PATCH 273/523] fixes factories method call --- spec/factories.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/factories.rb b/spec/factories.rb index c3e694025..90a725636 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -437,14 +437,14 @@ FactoryGirl.define do factory :poll_answer, class: 'Poll::Answer' do association :question, factory: :poll_question association :author, factory: :user - answer { question.verified_answers.sample } + answer { question.valid_answers.sample } end factory :poll_partial_result, class: 'Poll::PartialResult' do association :question, factory: :poll_question association :author, factory: :user origin { 'web' } - answer { question.verified_answers.sample } + answer { question.valid_answers.sample } end factory :organization do From 086f4a4170f1448cdf501b7a3ca15d8991451220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 14:19:36 +0100 Subject: [PATCH 274/523] refactors Poll::Voter --- app/models/poll/voter.rb | 57 +++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index dd8c85d8f..a2d46053a 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,33 +1,54 @@ class Poll class Voter < ActiveRecord::Base - belongs_to :booth_assignment belongs_to :poll + belongs_to :booth_assignment + belongs_to :answer - validates :booth_assignment, presence: true - validate :in_census - validate :has_not_voted validates :poll, presence: true - validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type] } - - def in_census - errors.add(:document_number, :not_in_census) unless census_api_response.valid? - end - - def has_not_voted - errors.add(:document_number, :has_voted, name: name) if has_voted? - end + validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted } def census_api_response - @census ||= CensusApi.new.call(document_type, document_number) + @census_api_response ||= CensusApi.new.call(document_type, document_number) end - def has_voted? - poll.document_has_voted?(document_number, document_type) + def in_census? + census_api_response.valid? end - def name - @census.name + def fill_stats_fields + if in_census? + self.gender = census_api_response.gender + self.geozone_id = Geozone.select(:id).where(census_code: census_api_response.district_code).first.try(:id) + self.age = voter_age(census_api_response.date_of_birth) + end end + def self.create_from_user(user, options = {}) + poll_id = options[:poll_id] + booth_assignment_id = options[:booth_assignment_id] + answer_id = options[:answer_id] + + Voter.create( + document_type: user.document_type, + document_number: user.document_number, + poll_id: poll_id, + booth_assignment_id: booth_assignment_id, + gender: user.gender, + geozone_id: user.geozone_id, + age: user.age, + answer_id: answer_id + ) + end + + private + + def voter_age(date_of_birth) + if date_of_birth.blank? + nil + else + ((Date.today - date_of_birth.to_date).to_i / 365.25).to_i + end + end + end end \ No newline at end of file From b13a76963af73795c5d27b64c2794c06c4e6e95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 14:21:03 +0100 Subject: [PATCH 275/523] records participation of user via web MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit answering a poll question creates a voter with the user data to record participation in question’s poll --- app/controllers/polls/questions_controller.rb | 1 + app/models/poll/answer.rb | 8 ++++ config/locales/activerecord.en.yml | 2 +- spec/factories.rb | 8 +++- spec/features/polls/questions_spec.rb | 16 +++++++ spec/models/poll/answer_spec.rb | 14 +++++++ spec/models/poll/poll_spec.rb | 7 ++-- spec/models/poll/voter_spec.rb | 42 +++++++++++-------- 8 files changed, 73 insertions(+), 25 deletions(-) diff --git a/app/controllers/polls/questions_controller.rb b/app/controllers/polls/questions_controller.rb index e9c7e2bbd..1849dff97 100644 --- a/app/controllers/polls/questions_controller.rb +++ b/app/controllers/polls/questions_controller.rb @@ -19,6 +19,7 @@ class Polls::QuestionsController < ApplicationController answer.answer = params[:answer] answer.save! + answer.record_voter_participation @answers_by_question_id = {@question.id => params[:answer]} end diff --git a/app/models/poll/answer.rb b/app/models/poll/answer.rb index b0f2d4410..2d08fefa4 100644 --- a/app/models/poll/answer.rb +++ b/app/models/poll/answer.rb @@ -3,6 +3,10 @@ class Poll::Answer < ActiveRecord::Base belongs_to :question, -> { with_hidden } belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' + has_one :voter + + delegate :poll, :poll_id, to: :question + validates :question, presence: true validates :author, presence: true validates :answer, presence: true @@ -10,4 +14,8 @@ class Poll::Answer < ActiveRecord::Base scope :by_author, -> (author_id) { where(author_id: author_id) } scope :by_question, -> (question_id) { where(question_id: question_id) } + + def record_voter_participation + Poll::Voter.create_from_user(author, {poll_id: poll_id, answer_id: id}) + end end \ No newline at end of file diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 302b6767a..6a7aebcbd 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -138,7 +138,7 @@ en: attributes: document_number: not_in_census: "Document not in census" - has_voted: "%{name} has already voted" + has_voted: "User has already voted" proposal: attributes: tag_list: diff --git a/spec/factories.rb b/spec/factories.rb index 90a725636..7653f9a3a 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -421,7 +421,11 @@ FactoryGirl.define do end factory :poll_voter, class: 'Poll::Voter' do - association :booth_assignment, factory: :poll_booth_assignment + poll + + trait :from_booth do + association :booth_assignment, factory: :poll_booth_assignment + end trait :valid_document do document_type "1" @@ -436,7 +440,7 @@ FactoryGirl.define do factory :poll_answer, class: 'Poll::Answer' do association :question, factory: :poll_question - association :author, factory: :user + association :author, factory: [:user, :level_three] answer { question.valid_answers.sample } end diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index e925c8fd6..d6d02b0cb 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -93,5 +93,21 @@ feature 'Poll Questions' do expect(page).to have_link('Chewbacca') end + scenario 'Records participarion', :js do + question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') + user = create(:user, :level_two, geozone: geozone) + + login_as user + visit question_path(question) + + click_link 'Han Solo' + + expect(page).to_not have_link('Han Solo') + + answer = Poll::Answer.by_question(question.id).by_author(user.id).first + expect(answer.voter.document_number).to eq(user.document_number) + expect(answer.voter.poll_id).to eq(poll.id) + end + end end diff --git a/spec/models/poll/answer_spec.rb b/spec/models/poll/answer_spec.rb index 73707ad80..effc28fde 100644 --- a/spec/models/poll/answer_spec.rb +++ b/spec/models/poll/answer_spec.rb @@ -13,4 +13,18 @@ describe Poll::Answer do end end + describe "#record_voter_participation" do + it "creates a poll_voter with user and poll data" do + answer = create(:poll_answer) + expect(answer.voter).to be_nil + + answer.record_voter_participation + voter = answer.reload.voter + + expect(voter.answer).to eq(answer) + expect(voter.document_number).to eq(answer.author.document_number) + expect(voter.poll_id).to eq(answer.poll.id) + end + end + end diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index e410c31ce..b2ec29e5c 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -64,15 +64,14 @@ describe :poll do describe "#document_has_voted?" do it "returns true if Poll::Voter with document exists" do - booth_assignment = create(:poll_booth_assignment, poll: poll) - voter = create(:poll_voter, :valid_document, booth_assignment: booth_assignment) + voter = create(:poll_voter, :valid_document, poll: poll) expect(poll.document_has_voted?(voter.document_number, voter.document_type)).to eq(true) end it "returns false if Poll::Voter with document does not exists" do - booth_assignment = create(:poll_booth_assignment) - voter = create(:poll_voter, :valid_document, booth_assignment: booth_assignment) + poll_2 = create(:poll) + voter = create(:poll_voter, :valid_document, poll: poll_2) expect(poll.document_has_voted?(voter.document_number, voter.document_type)).to eq(false) end diff --git a/spec/models/poll/voter_spec.rb b/spec/models/poll/voter_spec.rb index 3a1844f4b..88541dc82 100644 --- a/spec/models/poll/voter_spec.rb +++ b/spec/models/poll/voter_spec.rb @@ -8,36 +8,37 @@ describe :voter do describe "validations" do - it "should be valid if in census and has not voted" do - voter = build(:poll_voter, :valid_document, booth_assignment: booth_assignment) + it "should be valid if has not voted" do + voter = build(:poll_voter, :valid_document) expect(voter).to be_valid end - it "should not be valid if the user is not in the census" do - voter = build(:poll_voter, :invalid_document, booth_assignment: booth_assignment) - - expect(voter).to_not be_valid - expect(voter.errors.messages[:document_number]).to eq(["Document not in census"]) - end - - it "should not be valid if the user has already voted in the same booth/poll" do - voter1 = create(:poll_voter, :valid_document, booth_assignment: booth_assignment) - voter2 = build(:poll_voter, :valid_document, booth_assignment: booth_assignment) + it "should not be valid if the user has already voted in the same poll or booth_assignment" do + voter1 = create(:poll_voter, :valid_document, poll: poll) + voter2 = build(:poll_voter, :valid_document, poll: poll) expect(voter2).to_not be_valid - expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) + expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"]) + end + + it "should not be valid if the user has already voted in the same poll/booth" do + voter1 = create(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment) + voter2 = build(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment) + + expect(voter2).to_not be_valid + expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"]) end it "should not be valid if the user has already voted in different booth in the same poll" do booth_assignment1 = create(:poll_booth_assignment, poll: poll) booth_assignment2 = create(:poll_booth_assignment, poll: poll) - voter1 = create(:poll_voter, :valid_document, booth_assignment: booth_assignment1) - voter2 = build(:poll_voter, :valid_document, booth_assignment: booth_assignment2) + voter1 = create(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment1) + voter2 = build(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment2) expect(voter2).to_not be_valid - expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) + expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"]) end it "should be valid if the user has already voted in the same booth in different poll" do @@ -50,8 +51,13 @@ describe :voter do expect(voter2).to be_valid end - xit "should not be valid if the user has voted via web" do - pending "Implementation for voting via web" + it "should not be valid if the user has voted via web" do + answer = create(:poll_answer) + answer.record_voter_participation + + voter = build(:poll_voter, poll: answer.question.poll, document_number: answer.author.document_number, document_type: "1") + expect(voter).to_not be_valid + expect(voter.errors.messages[:document_number]).to eq(["User has already voted"]) end end From 754095f4d0c468a1b838a0503394397b9ac58056 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 17:15:38 +0100 Subject: [PATCH 276/523] fixes modified i18n key --- config/locales/activerecord.es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 644207b86..f55e82d1e 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -133,7 +133,7 @@ es: attributes: document_number: not_in_census: "Este documento no aparece en el censo" - has_voted: "%{name} ya ha votado" + has_voted: "Este usuario ya ha votado" proposal: attributes: tag_list: From cc6d841978448f0ae3648a0d2127e0398d396633 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Wed, 25 Jan 2017 17:16:17 +0100 Subject: [PATCH 277/523] refactors age calculation --- app/models/poll/voter.rb | 7 ++++--- app/models/user.rb | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index a2d46053a..4c9314f12 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -42,11 +42,12 @@ class Poll private - def voter_age(date_of_birth) - if date_of_birth.blank? + def voter_age(dob) + if dob.blank? nil else - ((Date.today - date_of_birth.to_date).to_i / 365.25).to_i + now = Time.now.utc.to_date + now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1) end end diff --git a/app/models/user.rb b/app/models/user.rb index 80b0cb621..7c72ab4b3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -250,7 +250,10 @@ class User < ActiveRecord::Base if date_of_birth.blank? nil else - ((Date.today - date_of_birth.to_date).to_i / 365.25).to_i + now = Time.now.utc.to_date + now.year - date_of_birth.year - ( + (now.month > date_of_birth.month || (now.month == date_of_birth.month && now.day >= date_of_birth.day) + ) ? 0 : 1) end end From d9351b123df64d68d46d6348349ceb97d8b48355 Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 25 Jan 2017 17:58:09 +0100 Subject: [PATCH 278/523] prints a button to redirect to the poll when a question is answerable --- app/views/polls/questions/show.html.erb | 29 +++++++++++++++---------- config/locales/en.yml | 1 + config/locales/es.yml | 1 + db/dev_seeds.rb | 13 ++++++++++- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/app/views/polls/questions/show.html.erb b/app/views/polls/questions/show.html.erb index 04d4a3372..c04490f7d 100644 --- a/app/views/polls/questions/show.html.erb +++ b/app/views/polls/questions/show.html.erb @@ -46,9 +46,23 @@
    - <% if @question.poll.current? %> - - <% if current_user.nil? %> + <% if can? :answer, @question %> +
    + <%= link_to t('poll_questions.show.answer_this_question'), + @question.poll, + class: 'large button' + %> +
    + <% else %> + <% if @question.poll.incoming? %> +
    + <%= t('poll_questions.show.cant_answer_incoming') %> +
    + <% elsif @question.poll.expired? %> +
    + <%= t('poll_questions.show.cant_answer_expired') %> +
    + <% elsif current_user.nil? %>
    <%= t("poll_questions.show.not_logged_in", signin: link_to(t("poll_questions.show.signin"), new_user_session_path, class: "probe-message"), @@ -70,15 +84,6 @@ <%= render "answers", question: @question %>
    - - <% elsif @question.poll.incoming? %> -
    - <%= t('poll_questions.show.cant_answer_expired') %> -
    - <% elsif @question.poll.expired? %> -
    - <%= t('poll_questions.show.cant_answer_incoming') %> -
    <% end %>
    diff --git a/config/locales/en.yml b/config/locales/en.yml index 2697fb396..b778c4166 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -416,6 +416,7 @@ en: create_question: "Create question" default_valid_answers: "Yes, No" show: + answer_this_question: "Answer this question" original_proposal: "Original proposal" author: "Created by" dates_title: "Participation dates" diff --git a/config/locales/es.yml b/config/locales/es.yml index 2ae41a5ce..abbe23ddf 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -416,6 +416,7 @@ es: create_question: "Crear pregunta para votación" default_valid_answers: "Sí, No" show: + answer_this_question: "Responder a esta pregunta" original_proposal: "Propuesta original" author: "Creado por" dates_title: "Fechas de participación" diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 066603e3c..6f10ca891 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -467,7 +467,14 @@ end puts "Creating polls" puts "Active Polls" -(1..5).each do |i| +(1..3).each do |i| + poll = Poll.create(name: "Active Poll #{i}", + starts_at: 1.month.ago, + ends_at: 1.month.from_now, + geozone_restricted: false) + puts " #{poll.name}" +end +(4..5).each do |i| poll = Poll.create(name: "Active Poll #{i}", starts_at: 1.month.ago, ends_at: 1.month.from_now, @@ -477,6 +484,10 @@ puts "Active Polls" puts " #{poll.name}" end + + + + puts "Upcoming Poll" poll = Poll.create(name: "Upcoming Poll", starts_at: 1.month.from_now, From d8b54d2adc2028c0f6a8086844a9dd043722fca1 Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 25 Jan 2017 18:43:30 +0100 Subject: [PATCH 279/523] fixes question specs --- spec/features/polls/questions_spec.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index af4c1058c..961fb4e46 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -62,8 +62,7 @@ feature 'Poll Questions' do login_as(create(:user, :level_two, geozone: geozone)) visit question_path(question) - expect(page).to have_link('Han Solo') - expect(page).to have_link('Chewbacca') + expect(page).to have_link('Answer this question') end scenario 'Level 2 users who have already answered' do @@ -75,9 +74,7 @@ feature 'Poll Questions' do login_as user visit question_path(question) - expect(page).to have_link('Han Solo') - expect(page).to_not have_link('Chewbacca') - expect(page).to have_content('Chewbacca') + expect(page).to have_link('Answer this question') end scenario 'Level 2 users answering', :js do @@ -87,10 +84,7 @@ feature 'Poll Questions' do login_as user visit question_path(question) - click_link 'Han Solo' - - expect(page).to_not have_link('Han Solo') - expect(page).to have_link('Chewbacca') + expect(page).to have_link('Answer this question') end end From 47abeff7faa68ae5829f8f4b0e36b34f19805a23 Mon Sep 17 00:00:00 2001 From: kikito Date: Thu, 26 Jan 2017 11:39:25 +0100 Subject: [PATCH 280/523] fixes specs --- spec/features/polls/questions_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index dd89be1cb..7b8c3495a 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -94,6 +94,7 @@ feature 'Poll Questions' do login_as user visit question_path(question) + click_link 'Answer this question' click_link 'Han Solo' expect(page).to_not have_link('Han Solo') From 51be80eedc90fd21948b1e4c5cc9a9ac4237060c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 27 Jan 2017 11:59:37 +0100 Subject: [PATCH 281/523] removes answer <-> voter association --- app/models/poll/answer.rb | 4 +--- app/models/poll/voter.rb | 5 +---- spec/features/polls/questions_spec.rb | 13 ++++++++----- spec/models/poll/answer_spec.rb | 6 +++--- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/app/models/poll/answer.rb b/app/models/poll/answer.rb index 2d08fefa4..84359e330 100644 --- a/app/models/poll/answer.rb +++ b/app/models/poll/answer.rb @@ -3,8 +3,6 @@ class Poll::Answer < ActiveRecord::Base belongs_to :question, -> { with_hidden } belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' - has_one :voter - delegate :poll, :poll_id, to: :question validates :question, presence: true @@ -16,6 +14,6 @@ class Poll::Answer < ActiveRecord::Base scope :by_question, -> (question_id) { where(question_id: question_id) } def record_voter_participation - Poll::Voter.create_from_user(author, {poll_id: poll_id, answer_id: id}) + Poll::Voter.create_from_user(author, {poll_id: poll_id}) end end \ No newline at end of file diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index 4c9314f12..ebf9d1475 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -2,7 +2,6 @@ class Poll class Voter < ActiveRecord::Base belongs_to :poll belongs_to :booth_assignment - belongs_to :answer validates :poll, presence: true validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted } @@ -26,7 +25,6 @@ class Poll def self.create_from_user(user, options = {}) poll_id = options[:poll_id] booth_assignment_id = options[:booth_assignment_id] - answer_id = options[:answer_id] Voter.create( document_type: user.document_type, @@ -35,8 +33,7 @@ class Poll booth_assignment_id: booth_assignment_id, gender: user.gender, geozone_id: user.geozone_id, - age: user.age, - answer_id: answer_id + age: user.age ) end diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index 7b8c3495a..d7d4f8c63 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -87,9 +87,9 @@ feature 'Poll Questions' do expect(page).to have_link('Answer this question') end - scenario 'Records participarion', :js do + scenario 'Records participation', :js do question = create(:poll_question, poll: poll, valid_answers: 'Han Solo, Chewbacca') - user = create(:user, :level_two, geozone: geozone) + user = create(:user, :level_two, geozone: geozone, gender: 'female', date_of_birth: 33.years.ago) login_as user visit question_path(question) @@ -99,9 +99,12 @@ feature 'Poll Questions' do expect(page).to_not have_link('Han Solo') - answer = Poll::Answer.by_question(question.id).by_author(user.id).first - expect(answer.voter.document_number).to eq(user.document_number) - expect(answer.voter.poll_id).to eq(poll.id) + voter = poll.voters.first + expect(voter.document_number).to eq(user.document_number) + expect(voter.geozone_id).to eq(user.geozone_id) + expect(voter.gender).to eq(user.gender) + expect(voter.age).to eq(33) + expect(voter.poll_id).to eq(poll.id) end end diff --git a/spec/models/poll/answer_spec.rb b/spec/models/poll/answer_spec.rb index effc28fde..10ccafbb6 100644 --- a/spec/models/poll/answer_spec.rb +++ b/spec/models/poll/answer_spec.rb @@ -16,12 +16,12 @@ describe Poll::Answer do describe "#record_voter_participation" do it "creates a poll_voter with user and poll data" do answer = create(:poll_answer) - expect(answer.voter).to be_nil + expect(answer.poll.voters).to be_blank answer.record_voter_participation - voter = answer.reload.voter + expect(answer.poll.reload.voters.size).to eq(1) + voter = answer.poll.voters.first - expect(voter.answer).to eq(answer) expect(voter.document_number).to eq(answer.author.document_number) expect(voter.poll_id).to eq(answer.poll.id) end From 3d28b317e2f73b2a8490da4d17a0dfff376d00f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 27 Jan 2017 15:18:35 +0100 Subject: [PATCH 282/523] recounts can be made from poll's first day --- app/controllers/officing/polls_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/officing/polls_controller.rb b/app/controllers/officing/polls_controller.rb index 0634bccb5..4841baa39 100644 --- a/app/controllers/officing/polls_controller.rb +++ b/app/controllers/officing/polls_controller.rb @@ -2,7 +2,7 @@ class Officing::PollsController < Officing::BaseController def index @polls = current_user.poll_officer? ? current_user.poll_officer.assigned_polls : [] - @polls = @polls.select {|poll| poll.current?(1.day.ago)} + @polls = @polls.select {|poll| poll.current?(Time.current) || poll.current?(1.day.ago)} end end \ No newline at end of file From e634e801139e2df7e9a010d1f8e4c884713e4d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 27 Jan 2017 15:19:03 +0100 Subject: [PATCH 283/523] adds system recounting to admin booth_assignments --- .../poll/booth_assignments_controller.rb | 3 +- app/helpers/poll_recounts_helper.rb | 7 ++ .../poll/booth_assignments/show.html.erb | 18 +++-- .../admin/poll/booth_assigments_spec.rb | 67 +++++++++++++++++-- 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 app/helpers/poll_recounts_helper.rb diff --git a/app/controllers/admin/poll/booth_assignments_controller.rb b/app/controllers/admin/poll/booth_assignments_controller.rb index 0f01ab462..64e67c6ca 100644 --- a/app/controllers/admin/poll/booth_assignments_controller.rb +++ b/app/controllers/admin/poll/booth_assignments_controller.rb @@ -24,7 +24,8 @@ class Admin::Poll::BoothAssignmentsController < Admin::BaseController def show @poll = ::Poll.find(params[:poll_id]) - @booth_assignment = @poll.booth_assignments.includes(:recounts, officer_assignments: [officer: [:user]]).find(params[:id]) + @booth_assignment = @poll.booth_assignments.includes(:recounts, :voters, officer_assignments: [officer: [:user]]).find(params[:id]) + @voters_by_date = @booth_assignment.voters.group_by {|v| v.created_at.to_date} end private diff --git a/app/helpers/poll_recounts_helper.rb b/app/helpers/poll_recounts_helper.rb new file mode 100644 index 000000000..1246e8f98 --- /dev/null +++ b/app/helpers/poll_recounts_helper.rb @@ -0,0 +1,7 @@ +module PollRecountsHelper + + def recount_for_date(recounts, date) + recounts.select {|r| r.date.to_date == date}.first + end + +end \ No newline at end of file diff --git a/app/views/admin/poll/booth_assignments/show.html.erb b/app/views/admin/poll/booth_assignments/show.html.erb index e62f17b95..2652ee2bb 100644 --- a/app/views/admin/poll/booth_assignments/show.html.erb +++ b/app/views/admin/poll/booth_assignments/show.html.erb @@ -59,13 +59,23 @@
    - <% @booth_assignment.recounts.sort_by{|r| r.date}.each do |recount| %> - - + <% (@poll.starts_at.to_date..@poll.ends_at.to_date).each do |voting_date| %> + <% recount = recount_for_date(@booth_assignment.recounts, voting_date) %> + <% system_count = @voters_by_date[voting_date].present? ? @voters_by_date[voting_date].size : 0 %> + <% if recount.present? %> + + - + + + <% else %> + + + + <% end %> + <% end %>
    <%= t("admin.poll_booth_assignments.show.date") %>
    <%= l recount.date.to_date %>
    <%= l voting_date %> <%= recount.count %>0<%= system_count %>
    <%= l voting_date %> - <%= system_count %>
    <% end %> diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index ff2ae833c..96939aa47 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -92,10 +92,22 @@ feature 'Admin booths assignments' do poll = create(:poll) booth = create(:poll_booth) booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) - recount = create(:poll_recount, booth_assignment: booth_assignment, count: 33) + officer_assignment_1 = create(:poll_officer_assignment, booth_assignment: booth_assignment, date: poll.starts_at) + officer_assignment_2 = create(:poll_officer_assignment, booth_assignment: booth_assignment, date: poll.ends_at) + + recount_1 = create(:poll_recount, + booth_assignment: booth_assignment, + officer_assignment: officer_assignment_1, + date: officer_assignment_1.date, + count: 33) + recount_2 = create(:poll_recount, + booth_assignment: booth_assignment, + officer_assignment: officer_assignment_2, + date: officer_assignment_2.date, + count: 1) booth_assignment_2 = create(:poll_booth_assignment, poll: poll) - recount_2 = create(:poll_recount, booth_assignment: booth_assignment_2, count: 100) + other_recount = create(:poll_recount, booth_assignment: booth_assignment_2, count: 100) visit admin_poll_path(poll) click_link 'Booths (2)' @@ -104,9 +116,56 @@ feature 'Admin booths assignments' do click_link 'Recounts' within('#recounts_list') do - expect(page).to have_content recount.count - expect(page).to_not have_content recount_2.count + expect(page).to_not have_content other_recount.count + + within("#recount_#{recount_1.id}") do + expect(page).to have_content recount_1.count + end + + within("#recount_#{recount_2.id}") do + expect(page).to have_content recount_2.count + end + end end + + scenario 'Marks recount values with count-errors' do + poll = create(:poll) + booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + today = Time.current.to_date + officer_assignment = create(:poll_officer_assignment, booth_assignment: booth_assignment, date: today) + + recount = create(:poll_recount, + booth_assignment: booth_assignment, + officer_assignment: officer_assignment, + date: officer_assignment.date, + count: 1) + + visit admin_poll_booth_assignment_path(poll, booth_assignment) + click_link 'Recounts' + + within('#recounts_list') do + expect(page).to have_css("#recount_#{recount.id}.count-error") + within("#recount_#{recount.id}") do + expect(page).to have_content recount.count + expect(page).to have_content 0 + end + end + + create(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment) + + visit admin_poll_booth_assignment_path(poll, booth_assignment) + click_link 'Recounts' + + within('#recounts_list') do + expect(page).to_not have_css('.count-error') + within("#recount_#{recount.id}") do + expect(page).to have_content(recount.count) + end + end + end + + end end \ No newline at end of file From cf6ca50a3bda99381da31f832cbe2d63dafed92b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 27 Jan 2017 18:39:25 +0100 Subject: [PATCH 284/523] adds optional officer_assignment_id to poll::voters --- app/models/poll/officer_assignment.rb | 1 + app/models/poll/voter.rb | 1 + .../20170127173553_add_officer_assignment_to_votes.rb | 5 +++++ db/schema.rb | 9 +++++---- spec/features/admin/poll/booth_assigments_spec.rb | 1 - 5 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20170127173553_add_officer_assignment_to_votes.rb diff --git a/app/models/poll/officer_assignment.rb b/app/models/poll/officer_assignment.rb index e192780cc..398149977 100644 --- a/app/models/poll/officer_assignment.rb +++ b/app/models/poll/officer_assignment.rb @@ -3,6 +3,7 @@ class Poll belongs_to :officer belongs_to :booth_assignment has_one :recount + has_many :voters validates :officer_id, presence: true validates :booth_assignment_id, presence: true diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index ebf9d1475..087771a02 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -2,6 +2,7 @@ class Poll class Voter < ActiveRecord::Base belongs_to :poll belongs_to :booth_assignment + belongs_to :officer_assignment validates :poll, presence: true validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted } diff --git a/db/migrate/20170127173553_add_officer_assignment_to_votes.rb b/db/migrate/20170127173553_add_officer_assignment_to_votes.rb new file mode 100644 index 000000000..1942ef08f --- /dev/null +++ b/db/migrate/20170127173553_add_officer_assignment_to_votes.rb @@ -0,0 +1,5 @@ +class AddOfficerAssignmentToVotes < ActiveRecord::Migration + def change + add_column :poll_voters, :officer_assignment_id, :integer, default: nil + end +end diff --git a/db/schema.rb b/db/schema.rb index 290703e9e..b1b45d475 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170125114952) do +ActiveRecord::Schema.define(version: 20170127173553) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -461,14 +461,15 @@ ActiveRecord::Schema.define(version: 20170125114952) do create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "poll_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "poll_id", null: false t.integer "booth_assignment_id" t.integer "age" t.string "gender" t.integer "geozone_id" t.integer "answer_id" + t.integer "officer_assignment_id" end add_index "poll_voters", ["document_number"], name: "index_poll_voters_on_document_number", using: :btree diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 96939aa47..28d612257 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -166,6 +166,5 @@ feature 'Admin booths assignments' do end end - end end \ No newline at end of file From f8d3e645db6549e5791e0e5abd4863753f9d81d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Sat, 28 Jan 2017 19:55:02 +0100 Subject: [PATCH 285/523] adds poll recounts to dev_seeds --- db/dev_seeds.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 6f10ca891..6541a007b 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -527,7 +527,7 @@ Poll::Booth.all.each do |booth| end puts "Creating Poll Officer Assignments" -(1..10).to_a.sample.times do |i| +(1..15).to_a.sample.times do |i| Poll::BoothAssignment.all.sample(i).each do |booth_assignment| Poll::OfficerAssignment.create(officer: poll_officer.poll_officer, booth_assignment: booth_assignment, @@ -535,6 +535,18 @@ puts "Creating Poll Officer Assignments" end end +puts "Creating Poll Recounts" do +(1..15).to_a.sample.times do |i| + poll_officer.poll_officer.officer_assignments.all.sample(i).each do |officer_assignment| + Poll::Recount.create(officer_assignment: officer_assignment, + booth_assignment: officer_assignment.booth_assignment, + date: officer_assignment.date, + count: (1..5000).to_a.sample) + end +end + +end + puts "Creating Poll Question from Proposals" (1..3).each do From ee4320f4c1131c609cd59202796d2e9f439bacc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Sat, 28 Jan 2017 20:05:01 +0100 Subject: [PATCH 286/523] removes noise from dev_seeds output --- db/dev_seeds.rb | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 6541a007b..5ad69a07a 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -51,7 +51,6 @@ puts "Creating Users" def create_user(email, username = Faker::Name.name) pwd = '12345678' - puts " #{username}" User.create!(username: username, email: email, password: pwd, password_confirmation: pwd, confirmed_at: Time.current, terms_of_service: "1") end @@ -141,7 +140,6 @@ tags = Faker::Lorem.words(25) tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1") - puts " #{debate.title}" end @@ -156,7 +154,6 @@ tags = ActsAsTaggableOn::Tag.where(kind: 'category') tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1") - puts " #{debate.title}" end @@ -177,7 +174,6 @@ tags = Faker::Lorem.words(25) tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1") - puts " #{proposal.title}" end puts "Creating Archived Proposals" @@ -197,7 +193,6 @@ tags = Faker::Lorem.words(25) geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1", created_at: Setting["months_to_archive_proposals"].to_i.months.ago) - puts " #{proposal.title}" end puts "Creating Successful Proposals" @@ -218,7 +213,6 @@ tags = Faker::Lorem.words(25) geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1", cached_votes_up: Setting["votes_for_proposal_success"]) - puts " #{proposal.title}" end @@ -237,7 +231,6 @@ tags = ActsAsTaggableOn::Tag.where(kind: 'category') tag_list: tags.sample(3).join(','), geozone: Geozone.reorder("RANDOM()").first, terms_of_service: "1") - puts " #{proposal.title}" end @@ -345,7 +338,6 @@ tags = Faker::Lorem.words(10) tag_list: tags.sample(3).join(','), price: rand(1000000), terms_of_service: "1") - puts " #{spending_proposal.title}" end puts "Creating Valuation Assignments" @@ -368,8 +360,6 @@ Budget::PHASES.each_with_index do |phase, i| ) ) - puts budget.name - (1..([1, 2, 3].sample)).each do group = budget.groups.create!(name: Faker::StarWars.planet) @@ -380,9 +370,7 @@ Budget::PHASES.each_with_index do |phase, i| price: rand(1 .. 100) * 100000) end - print "#{group.name} " end - puts "" end @@ -406,7 +394,6 @@ tags = Faker::Lorem.words(10) tag_list: tags.sample(3).join(','), price: rand(1 .. 100) * 100000, terms_of_service: "1") - puts " #{investment.title}" end puts "Selecting Investments" @@ -461,7 +448,6 @@ Proposal.last(3).each do |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)), created_at: rand((Time.current - 1.week) .. Time.current)) - puts " #{banner.title}" end puts "Creating polls" @@ -472,7 +458,6 @@ puts "Active Polls" starts_at: 1.month.ago, ends_at: 1.month.from_now, geozone_restricted: false) - puts " #{poll.name}" end (4..5).each do |i| poll = Poll.create(name: "Active Poll #{i}", @@ -481,7 +466,6 @@ end geozone_restricted: true, geozones: Geozone.reorder("RANDOM()").limit(3) ) - puts " #{poll.name}" end @@ -492,13 +476,11 @@ puts "Upcoming Poll" poll = Poll.create(name: "Upcoming Poll", starts_at: 1.month.from_now, ends_at: 2.months.from_now) -puts " #{poll.name}" puts "Expired Poll" poll = Poll.create(name: "Expired Poll", starts_at: 2.months.ago, ends_at: 1.months.ago) -puts " #{poll.name}" puts "Creating Poll Questions" @@ -513,7 +495,6 @@ puts "Creating Poll Questions" description: description, valid_answers: Faker::Lorem.words(3).join(', '), poll: poll) - puts " #{question.title}" end puts "Creating Poll Booths" @@ -547,7 +528,7 @@ end end -puts "Creating Poll Question from Proposals" +puts "Creating Poll Questions from Proposals" (1..3).each do proposal = Proposal.reorder("RANDOM()").first @@ -555,8 +536,6 @@ puts "Creating Poll Question from Proposals" question = Poll::Question.create(valid_answers: "Yes, No") question.copy_attributes_from_proposal(proposal) question.save! - - puts " #{question.title} (from proposal)" end puts "Creating Successful Proposals" @@ -567,8 +546,6 @@ puts "Creating Successful Proposals" question = Poll::Question.create(valid_answers: "Yes, No") question.copy_attributes_from_proposal(proposal) question.save! - - puts " #{question.title} (from proposal)" end puts "Commenting Poll Questions" From e07ebc79672d1c9cd805f0df29fd2a2b0af4f8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Sat, 28 Jan 2017 20:17:20 +0100 Subject: [PATCH 287/523] beautifies dev_seeds output --- db/dev_seeds.rb | 110 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 5ad69a07a..da6304384 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -2,7 +2,7 @@ require 'database_cleaner' DatabaseCleaner.clean_with :truncation -puts "Creating Settings" +print "Creating Settings" Setting.create(key: 'official_level_1_name', value: 'Empleados públicos') Setting.create(key: 'official_level_2_name', value: 'Organización Municipal') Setting.create(key: 'official_level_3_name', value: 'Directores generales') @@ -42,12 +42,14 @@ Setting.create(key: 'meta_keywords', value: 'citizen participation, open governm Setting.create(key: 'verification_offices_url', value: 'http://oficinas-atencion-ciudadano.url/') Setting.create(key: 'min_age_to_participate', value: '16') -puts "Creating Geozones" +puts " ✅" +print "Creating Geozones" Geozone.create(name: "city") ('A'..'Z').each { |i| Geozone.create(name: "District #{i}", external_code: i.ord, census_code: i.ord) } -puts "Creating Users" +puts " ✅" +print "Creating Users" def create_user(email, username = Faker::Name.name) pwd = '12345678' @@ -109,7 +111,8 @@ end org_user_ids = User.organizations.pluck(:id) not_org_users = User.where(['users.id NOT IN(?)', org_user_ids]) -puts "Creating Tags Categories" +puts " ✅" +print "Creating Tags Categories" ActsAsTaggableOn::Tag.create!(name: "Asociaciones", featured: true, kind: "category") ActsAsTaggableOn::Tag.create!(name: "Cultura", featured: true, kind: "category") @@ -127,7 +130,8 @@ ActsAsTaggableOn::Tag.create!(name: "Transparencia", featured: true, kind: "cat ActsAsTaggableOn::Tag.create!(name: "Seguridad y Emergencias", featured: true, kind: "category") ActsAsTaggableOn::Tag.create!(name: "Medio Ambiente", featured: true, kind: "category") -puts "Creating Debates" +puts " ✅" +print "Creating Debates" tags = Faker::Lorem.words(25) (1..30).each do @@ -157,7 +161,8 @@ tags = ActsAsTaggableOn::Tag.where(kind: 'category') end -puts "Creating Proposals" +puts " ✅" +print "Creating Proposals" tags = Faker::Lorem.words(25) (1..30).each do |i| @@ -176,7 +181,8 @@ tags = Faker::Lorem.words(25) terms_of_service: "1") end -puts "Creating Archived Proposals" +puts " ✅" +print "Creating Archived Proposals" tags = Faker::Lorem.words(25) (1..5).each do @@ -195,7 +201,8 @@ tags = Faker::Lorem.words(25) created_at: Setting["months_to_archive_proposals"].to_i.months.ago) end -puts "Creating Successful Proposals" +puts " ✅" +print "Creating Successful Proposals" tags = Faker::Lorem.words(25) (1..10).each do |i| @@ -234,7 +241,8 @@ tags = ActsAsTaggableOn::Tag.where(kind: 'category') end -puts "Commenting Debates" +puts " ✅" +print "Commenting Debates" (1..100).each do author = User.reorder("RANDOM()").first @@ -246,7 +254,8 @@ puts "Commenting Debates" end -puts "Commenting Proposals" +puts " ✅" +print "Commenting Proposals" (1..100).each do |i| author = User.reorder("RANDOM()").first @@ -258,7 +267,8 @@ puts "Commenting Proposals" end -puts "Commenting Comments" +puts " ✅" +print "Commenting Comments" (1..200).each do author = User.reorder("RANDOM()").first @@ -272,7 +282,8 @@ puts "Commenting Comments" end -puts "Voting Debates, Proposals & Comments" +puts " ✅" +print "Voting Debates, Proposals & Comments" (1..100).each do voter = not_org_users.reorder("RANDOM()").first @@ -295,7 +306,8 @@ end end -puts "Flagging Debates & Comments" +puts " ✅" +print "Flagging Debates & Comments" (1..40).each do debate = Debate.reorder("RANDOM()").first @@ -315,7 +327,8 @@ end Flag.flag(flagger, proposal) end -puts "Creating Spending Proposals" +puts " ✅" +print "Creating Spending Proposals" tags = Faker::Lorem.words(10) @@ -340,14 +353,16 @@ tags = Faker::Lorem.words(10) terms_of_service: "1") end -puts "Creating Valuation Assignments" +puts " ✅" +print "Creating Valuation Assignments" (1..17).to_a.sample.times do SpendingProposal.reorder("RANDOM()").first.valuators << valuator.valuator end -puts "Creating Budgets" +puts " ✅" +print "Creating Budgets" Budget::PHASES.each_with_index do |phase, i| descriptions = Hash[Budget::PHASES.map{ |p| ["description_#{p}", @@ -374,7 +389,8 @@ Budget::PHASES.each_with_index do |phase, i| end -puts "Creating Investments" +puts " ✅" +print "Creating Investments" tags = Faker::Lorem.words(10) (1..100).each do |i| heading = Budget::Heading.reorder("RANDOM()").first @@ -396,44 +412,51 @@ tags = Faker::Lorem.words(10) terms_of_service: "1") end -puts "Selecting Investments" +puts " ✅" +print "Selecting Investments" Budget.balloting.reorder("RANDOM()").limit(3).each do |budget| budget.investments.feasible.reorder("RANDOM()").limit(10).update_all(selected: true) end -puts "Creating Valuation Assignments" +puts " ✅" +print "Creating Valuation Assignments" (1..17).to_a.sample.times do Budget::Investment.reorder("RANDOM()").first.valuators << valuator.valuator end -puts "Creating Legislation" +puts " ✅" +print "Creating Legislation" Legislation.create!(title: 'Participatory Democracy', body: 'In order to achieve...') -puts "Ignoring flags in Debates, comments & proposals" +puts " ✅" +print "Ignoring flags in Debates, comments & proposals" Debate.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) Comment.flagged.reorder("RANDOM()").limit(30).each(&:ignore_flag) Proposal.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) -puts "Hiding debates, comments & proposals" +puts " ✅" +print "Hiding debates, comments & proposals" Comment.with_hidden.flagged.reorder("RANDOM()").limit(30).each(&:hide) Debate.with_hidden.flagged.reorder("RANDOM()").limit(5).each(&:hide) Proposal.with_hidden.flagged.reorder("RANDOM()").limit(10).each(&:hide) -puts "Confirming hiding in debates, comments & proposals" +puts " ✅" +print "Confirming hiding in debates, comments & proposals" Comment.only_hidden.flagged.reorder("RANDOM()").limit(10).each(&:confirm_hide) Debate.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide) Proposal.only_hidden.flagged.reorder("RANDOM()").limit(5).each(&:confirm_hide) -puts "Creating banners" +puts " ✅" +print "Creating banners" Proposal.last(3).each do |proposal| title = Faker::Lorem.sentence(word_count = 3) @@ -450,9 +473,11 @@ Proposal.last(3).each do |proposal| created_at: rand((Time.current - 1.week) .. Time.current)) end -puts "Creating polls" +puts " ✅" +print "Creating polls" -puts "Active Polls" +puts " ✅" +print "Active Polls" (1..3).each do |i| poll = Poll.create(name: "Active Poll #{i}", starts_at: 1.month.ago, @@ -472,17 +497,20 @@ end -puts "Upcoming Poll" +puts " ✅" +print "Upcoming Poll" poll = Poll.create(name: "Upcoming Poll", starts_at: 1.month.from_now, ends_at: 2.months.from_now) -puts "Expired Poll" +puts " ✅" +print "Expired Poll" poll = Poll.create(name: "Expired Poll", starts_at: 2.months.ago, ends_at: 1.months.ago) -puts "Creating Poll Questions" +puts " ✅" +print "Creating Poll Questions" (1..50).each do |i| poll = Poll.reorder("RANDOM()").first @@ -497,17 +525,20 @@ puts "Creating Poll Questions" poll: poll) end -puts "Creating Poll Booths" +puts " ✅" +print "Creating Poll Booths" 30.times.each_with_index do |i| Poll::Booth.create(name: "Booth #{i}", polls: [Poll.all.sample]) end -puts "Creating Booth Assignments" +puts " ✅" +print "Creating Booth Assignments" Poll::Booth.all.each do |booth| Poll::BoothAssignment.create(booth: booth, poll: Poll.all.sample) end -puts "Creating Poll Officer Assignments" +puts " ✅" +print "Creating Poll Officer Assignments" (1..15).to_a.sample.times do |i| Poll::BoothAssignment.all.sample(i).each do |booth_assignment| Poll::OfficerAssignment.create(officer: poll_officer.poll_officer, @@ -516,7 +547,8 @@ puts "Creating Poll Officer Assignments" end end -puts "Creating Poll Recounts" do +puts " ✅" +print "Creating Poll Recounts" do (1..15).to_a.sample.times do |i| poll_officer.poll_officer.officer_assignments.all.sample(i).each do |officer_assignment| Poll::Recount.create(officer_assignment: officer_assignment, @@ -528,7 +560,8 @@ end end -puts "Creating Poll Questions from Proposals" +puts " ✅" +print "Creating Poll Questions from Proposals" (1..3).each do proposal = Proposal.reorder("RANDOM()").first @@ -538,7 +571,8 @@ puts "Creating Poll Questions from Proposals" question.save! end -puts "Creating Successful Proposals" +puts " ✅" +print "Creating Successful Proposals" (1..10).each do proposal = Proposal.reorder("RANDOM()").first @@ -548,7 +582,8 @@ puts "Creating Successful Proposals" question.save! end -puts "Commenting Poll Questions" +puts " ✅" +print "Commenting Poll Questions" (1..30).each do author = User.reorder("RANDOM()").first @@ -558,3 +593,6 @@ puts "Commenting Poll Questions" commentable: question, body: Faker::Lorem.sentence) end + +puts " ✅" +puts "All dev seeds created succesfully 👍" \ No newline at end of file From 8b19dcfbd8d58a65b15b718fc26174d468ee9135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Sat, 28 Jan 2017 20:29:45 +0100 Subject: [PATCH 288/523] fixes typo --- db/dev_seeds.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index da6304384..c0183d2fc 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -595,4 +595,4 @@ print "Commenting Poll Questions" end puts " ✅" -puts "All dev seeds created succesfully 👍" \ No newline at end of file +puts "All dev seeds created successfuly 👍" \ No newline at end of file From 6c34599e1e26aca962c1031eb0d806fe7ba010ac Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 29 Jan 2017 00:36:20 +0100 Subject: [PATCH 289/523] adds officer residence check and user voting --- app/controllers/officing/base_controller.rb | 4 +- .../officing/residence_controller.rb | 21 ++++ app/controllers/officing/voters_controller.rb | 19 ++++ app/models/officing/residence.rb | 107 ++++++++++++++++++ app/models/poll.rb | 4 + app/models/poll/answer.rb | 2 +- app/models/poll/voter.rb | 63 ++++++----- app/views/officing/_menu.html.erb | 2 +- app/views/officing/residence/_errors.html.erb | 14 +++ app/views/officing/residence/new.html.erb | 26 +++++ .../officing/voters/_already_voted.html.erb | 3 + app/views/officing/voters/_can_vote.html.erb | 7 ++ app/views/officing/voters/_voted.html.erb | 3 + app/views/officing/voters/create.js.erb | 1 + app/views/officing/voters/new.html.erb | 27 ++--- app/views/officing/voters/show.html.erb | 30 ----- config/locales/officing.en.yml | 17 ++- config/locales/officing.es.yml | 15 ++- config/routes.rb | 3 +- db/dev_seeds.rb | 9 ++ ...70128214244_adds_user_id_to_poll_voters.rb | 5 + db/schema.rb | 4 +- spec/factories.rb | 16 +++ spec/features/officing/residence_spec.rb | 50 ++++++++ spec/features/officing/voters_spec.rb | 55 +++++++++ spec/features/polls/questions_spec.rb | 1 + spec/models/officing/residence_spec.rb | 87 ++++++++++++++ spec/models/poll/voter_spec.rb | 47 ++++++++ spec/spec_helper.rb | 7 +- spec/support/common_actions.rb | 10 ++ 30 files changed, 570 insertions(+), 89 deletions(-) create mode 100644 app/controllers/officing/residence_controller.rb create mode 100644 app/models/officing/residence.rb create mode 100644 app/views/officing/residence/_errors.html.erb create mode 100644 app/views/officing/residence/new.html.erb create mode 100644 app/views/officing/voters/_already_voted.html.erb create mode 100644 app/views/officing/voters/_can_vote.html.erb create mode 100644 app/views/officing/voters/_voted.html.erb create mode 100644 app/views/officing/voters/create.js.erb delete mode 100644 app/views/officing/voters/show.html.erb create mode 100644 db/migrate/20170128214244_adds_user_id_to_poll_voters.rb create mode 100644 spec/features/officing/residence_spec.rb create mode 100644 spec/features/officing/voters_spec.rb create mode 100644 spec/models/officing/residence_spec.rb diff --git a/app/controllers/officing/base_controller.rb b/app/controllers/officing/base_controller.rb index 271f62daa..97ef23d30 100644 --- a/app/controllers/officing/base_controller.rb +++ b/app/controllers/officing/base_controller.rb @@ -7,6 +7,6 @@ class Officing::BaseController < ApplicationController skip_authorization_check def verify_officer - raise CanCan::AccessDenied unless current_user.try(:poll_officer?) || current_user.try(:administrator?) - end + raise CanCan::AccessDenied unless current_user.try(:poll_officer?) || current_user.try(:administrator?) + end end \ No newline at end of file diff --git a/app/controllers/officing/residence_controller.rb b/app/controllers/officing/residence_controller.rb new file mode 100644 index 000000000..768bac21f --- /dev/null +++ b/app/controllers/officing/residence_controller.rb @@ -0,0 +1,21 @@ +class Officing::ResidenceController < Officing::BaseController + + def new + @residence = Officing::Residence.new + end + + def create + @residence = Officing::Residence.new(residence_params) + if @residence.save + redirect_to new_officing_voter_path(id: @residence.user.id), notice: t("officing.residence.flash.create") + else + render :new + end + end + + private + + def residence_params + params.require(:residence).permit(:document_number, :document_type, :date_of_birth) + end +end \ No newline at end of file diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb index 6cf321beb..bb16a1412 100644 --- a/app/controllers/officing/voters_controller.rb +++ b/app/controllers/officing/voters_controller.rb @@ -1,6 +1,25 @@ class Officing::VotersController < Officing::BaseController + respond_to :html, :js def new + @user = User.find(params[:id]) + @polls = Poll.current # fix and use answerable_by(@user) end + def create + @poll = Poll.find(voter_params[:poll_id]) + @user = User.find(voter_params[:user_id]) + @voter = Poll::Voter.new(document_type: @user.document_type, + document_number: @user.document_number, + user: @user, + poll: @poll) + @voter.save! + end + + private + + def voter_params + params.require(:voter).permit(:poll_id, :user_id) + end + end \ No newline at end of file diff --git a/app/models/officing/residence.rb b/app/models/officing/residence.rb new file mode 100644 index 000000000..2a8cca51d --- /dev/null +++ b/app/models/officing/residence.rb @@ -0,0 +1,107 @@ +class Officing::Residence + include ActiveModel::Model + include ActiveModel::Dates + include ActiveModel::Validations::Callbacks + + attr_accessor :user, :officer, :document_number, :document_type, :date_of_birth + + before_validation :call_census_api + + validates_presence_of :document_number + validates_presence_of :document_type + validates_presence_of :date_of_birth + + validate :allowed_age + validate :residence_in_madrid + + def initialize(attrs={}) + self.date_of_birth = parse_date('date_of_birth', attrs) + attrs = remove_date('date_of_birth', attrs) + super + clean_document_number + end + + def save + return false unless valid? + + if user_exists? + self.user = find_user_by_document + else + user_params = { + document_number: document_number, + document_type: document_type, + geozone: self.geozone, + date_of_birth: date_of_birth.to_datetime, + gender: gender, + residence_verified_at: Time.current, + verified_at: Time.current, + erased_at: Time.current, + password: random_password, + terms_of_service: '1', + email: nil + } + self.user = User.create!(user_params) + end + end + + def user_exists? + find_user_by_document.present? + end + + def find_user_by_document + User.where(document_number: document_number, + document_type: document_type).first + end + + def residence_in_madrid + return if errors.any? + + unless residency_valid? + errors.add(:residence_in_madrid, false) + end + end + + def allowed_age + return if errors[:date_of_birth].any? + + unless allowed_age? + errors.add(:date_of_birth, I18n.t('verification.residence.new.error_not_allowed_age')) + end + end + + def allowed_age? + self.date_of_birth <= User.minimum_required_age.years.ago + end + + def geozone + Geozone.where(census_code: district_code).first + end + + def district_code + @census_api_response.district_code + end + + def gender + @census_api_response.gender + end + + private + + def call_census_api + @census_api_response = CensusApi.new.call(document_type, document_number) + end + + def residency_valid? + @census_api_response.valid? && + @census_api_response.date_of_birth == date_of_birth + end + + def clean_document_number + self.document_number = self.document_number.gsub(/[^a-z0-9]+/i, "").upcase unless self.document_number.blank? + end + + def random_password + (0...20).map { ('a'..'z').to_a[rand(26)] }.join + end + +end diff --git a/app/models/poll.rb b/app/models/poll.rb index c5da9dcd0..761a4561f 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -44,6 +44,10 @@ class Poll < ActiveRecord::Base current.joins(:geozones).where('geozone_restricted = ? or geozones.id = ?', false, user.geozone_id) end + def votable_by?(user) + !document_has_voted?(user.document_number, user.document_type) + end + def document_has_voted?(document_number, document_type) voters.where(document_number: document_number, document_type: document_type).exists? end diff --git a/app/models/poll/answer.rb b/app/models/poll/answer.rb index 84359e330..52fb11469 100644 --- a/app/models/poll/answer.rb +++ b/app/models/poll/answer.rb @@ -14,6 +14,6 @@ class Poll::Answer < ActiveRecord::Base scope :by_question, -> (question_id) { where(question_id: question_id) } def record_voter_participation - Poll::Voter.create_from_user(author, {poll_id: poll_id}) + Poll::Voter.create!(user: author, poll: poll) end end \ No newline at end of file diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index ebf9d1475..1ff80605a 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,44 +1,53 @@ class Poll class Voter < ActiveRecord::Base belongs_to :poll + belongs_to :user + belongs_to :geozone belongs_to :booth_assignment - validates :poll, presence: true + validates :poll_id, presence: true + validates :user_id, presence: true + validates :geozone_id, presence: true + validates :gender, presence: true + validates :age, presence: true + validates :document_number, presence: true, uniqueness: { scope: [:poll_id, :document_type], message: :has_voted } - def census_api_response - @census_api_response ||= CensusApi.new.call(document_type, document_number) + before_validation :set_demographic_info, :set_document_info + + def set_demographic_info + return unless user.present? + + self.gender = user.gender + self.age = user.age + self.geozone = user.geozone end - def in_census? - census_api_response.valid? - end + def set_document_info + return unless user.present? - def fill_stats_fields - if in_census? - self.gender = census_api_response.gender - self.geozone_id = Geozone.select(:id).where(census_code: census_api_response.district_code).first.try(:id) - self.age = voter_age(census_api_response.date_of_birth) - end - end - - def self.create_from_user(user, options = {}) - poll_id = options[:poll_id] - booth_assignment_id = options[:booth_assignment_id] - - Voter.create( - document_type: user.document_type, - document_number: user.document_number, - poll_id: poll_id, - booth_assignment_id: booth_assignment_id, - gender: user.gender, - geozone_id: user.geozone_id, - age: user.age - ) + self.document_type = user.document_type + self.document_number = user.document_number end private + def in_census? + census_api_response.valid? + end + + def census_api_response + @census_api_response ||= CensusApi.new.call(document_type, document_number) + end + + def fill_stats_fields + if in_census? + self.gender = census_api_response.gender + self.geozone_id = Geozone.select(:id).where(census_code: census_api_response.district_code).first.try(:id) + self.age = voter_age(census_api_response.date_of_birth) + end + end + def voter_age(dob) if dob.blank? nil diff --git a/app/views/officing/_menu.html.erb b/app/views/officing/_menu.html.erb index d999fc06b..40484a90a 100644 --- a/app/views/officing/_menu.html.erb +++ b/app/views/officing/_menu.html.erb @@ -2,7 +2,7 @@
    • > - <%= link_to new_officing_poll_voter_path(Poll.last) do %> + <%= link_to new_officing_residence_path do %> <%= t("officing.menu.voters") %> <% end %> diff --git a/app/views/officing/residence/_errors.html.erb b/app/views/officing/residence/_errors.html.erb new file mode 100644 index 000000000..4f8895a35 --- /dev/null +++ b/app/views/officing/residence/_errors.html.erb @@ -0,0 +1,14 @@ +<% if @residence.errors[:residence_in_madrid].present? %> + +
      + + <%= t("officing.residence.new.error_verifying_census") %> +
      + +<% else %> + <%= render "shared/errors", + resource: @residence, + message: t("officing.residence.new.form_errors") %> +<% end %> diff --git a/app/views/officing/residence/new.html.erb b/app/views/officing/residence/new.html.erb new file mode 100644 index 000000000..45290762e --- /dev/null +++ b/app/views/officing/residence/new.html.erb @@ -0,0 +1,26 @@ +

      <%= t("officing.residence.new.title") %>

      + +
      +
      + <%= form_for @residence, as: "residence", url: officing_residence_path do |f| %> + <%= render "errors" %> + + <%= f.label t("officing.residence.new.document_type_label") %> + <%= f.select :document_type, document_types, prompt: "", label: false %> + + + <%= f.text_field :document_number, + placeholder: t("officing.residence.new.document_number") %> + +
      + <%= f.label t("verification.residence.new.date_of_birth") %> + <%= f.date_select :date_of_birth, + prompt: true, + start_year: 1900, end_year: 16.years.ago.year, + label: false %> +
      + + " class="button"> + <% end %> +
      +
      diff --git a/app/views/officing/voters/_already_voted.html.erb b/app/views/officing/voters/_already_voted.html.erb new file mode 100644 index 000000000..847d8b7d7 --- /dev/null +++ b/app/views/officing/voters/_already_voted.html.erb @@ -0,0 +1,3 @@ +
      + <%= t("officing.voters.show.error_already_voted") %> +
      \ No newline at end of file diff --git a/app/views/officing/voters/_can_vote.html.erb b/app/views/officing/voters/_can_vote.html.erb new file mode 100644 index 000000000..66a9a5e62 --- /dev/null +++ b/app/views/officing/voters/_can_vote.html.erb @@ -0,0 +1,7 @@ +
      + <%= form_for @user, as: :voter, url: officing_voters_path, method: :post, remote: true do |f| %> + <%= f.hidden_field :poll_id, value: poll.id %> + <%= f.hidden_field :user_id, value: @user.id %> + <%= f.submit t("officing.voters.show.submit"), class: "button success expanded" %> + <% end %> +
      \ No newline at end of file diff --git a/app/views/officing/voters/_voted.html.erb b/app/views/officing/voters/_voted.html.erb new file mode 100644 index 000000000..f2c6547cf --- /dev/null +++ b/app/views/officing/voters/_voted.html.erb @@ -0,0 +1,3 @@ +
      + <%= t("officing.voters.show.success") %> +
      \ No newline at end of file diff --git a/app/views/officing/voters/create.js.erb b/app/views/officing/voters/create.js.erb new file mode 100644 index 000000000..ee280faa2 --- /dev/null +++ b/app/views/officing/voters/create.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id(@poll) %> #actions").html('<%= j render("voted") %>'); \ No newline at end of file diff --git a/app/views/officing/voters/new.html.erb b/app/views/officing/voters/new.html.erb index 2042f7acb..8fdeb512a 100644 --- a/app/views/officing/voters/new.html.erb +++ b/app/views/officing/voters/new.html.erb @@ -1,20 +1,15 @@

      <%= t("officing.voters.new.title") %>

      -
      -
      -
      +<% @polls.each do |poll| %> +
      +
      <%= poll.name %>
      - - - - - "> - - " class="button"> - +
      + <% if poll.votable_by?(@user) %> + <%= render "can_vote", poll: poll %> + <% else %> + <%= render "already_voted" %> + <% end %> +
      -
      +<% end %> \ No newline at end of file diff --git a/app/views/officing/voters/show.html.erb b/app/views/officing/voters/show.html.erb deleted file mode 100644 index 523e0e0d4..000000000 --- a/app/views/officing/voters/show.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -

      <%= t("officing.voters.show.title") %>

      - - - -
      - <%= t("officing.voters.show.error_verifying_census") %> -
      - - - -
      - <%= t("officing.voters.show.error_already_voted") %> -
      - - - -
      - <%= t("officing.voters.show.can_participate") %> -
      - -
      -
      - " class="button success expanded"> -
      -
      - - -
      - <%= t("officing.voters.show.success") %> -
      \ No newline at end of file diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index fad63ee4e..2d8d77e13 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -29,7 +29,9 @@ en: recount_list: "Your recounts" booth: "Booth" date: "Date" - voters: + residence: + flash: + create: "Document verified with Census" new: title: Validate document document_number: Document number @@ -39,10 +41,15 @@ en: spanish_id: DNI document_type_label: Document type submit: Validate document + error_verifying_census: "The Census was unable to verify this document." + error_not_allowed_age: You don't have the required age to participate + error_verifying_census_offices: Citizen Support Office + form_errors: prevented the verification of this document + voters: + new: + title: Polls show: title: Validate document - error_verifying_census: "The Census was unable to verify the information of this document." - error_already_voted: "The person associated with the document has already participated in the vote." - can_participate: "The person associated with the document can participate in the vote." + error_already_voted: Has already participated in this poll submit: Validate vote - success: "Vote validated correctly." + success: Vote validated successfully. diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index 1a8bccb13..827aea9d5 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -29,7 +29,9 @@ es: recount_list: "Tus recuentos" booth: "Urna" date: "Fecha" - voters: + residence: + flash: + create: "Documento verificado con el Padrón" new: title: Validar documento document_number: Número de documento @@ -39,10 +41,15 @@ es: spanish_id: DNI document_type_label: Tipo de documento submit: Validar documento + error_not_allowed_age: No tienes la edad mínima para participar + error_verifying_census: El Padrón no pudo verificar este documento. + form_errors: evitaron verificar este documento + voters: + new: + title: Votaciones show: title: Validar documento - error_verifying_census: "El Padrón no pudo verificar la información de este documento." - error_already_voted: "La persona asociada al documento ya ha participado en la votación." + error_already_voted: "Ya ha participado en la votación." can_participate: "La persona asociada al documento puede participar en la votación." submit: Validar voto - success: "Voto validado correctamente." + success: Voto validado correctamente. diff --git a/config/routes.rb b/config/routes.rb index 5bfdf8ee9..2a0a157c2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -333,8 +333,9 @@ Rails.application.routes.draw do namespace :officing do resources :polls, only: [:index] do resources :recounts, only: [:new, :create] - resources :voters, only: [:new, :show] end + resource :residence, controller: "residence", only: [:new, :create] + resources :voters, only: [:new, :create] root to: "dashboard#index" end diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 6f10ca891..c203969b4 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -45,6 +45,7 @@ Setting.create(key: 'min_age_to_participate', value: '16') puts "Creating Geozones" Geozone.create(name: "city") +Geozone.create(name: "Existent District", census_code: "01") ('A'..'Z').each { |i| Geozone.create(name: "District #{i}", external_code: i.ord, census_code: i.ord) } puts "Creating Users" @@ -569,3 +570,11 @@ puts "Commenting Poll Questions" commentable: question, body: Faker::Lorem.sentence) end + +puts "Creating Poll Voters" + +(1..10).each do + poll = Poll.all.sample + document_number = Faker::Number.number(10) + Poll::Voter.create!(poll: poll, document_number: document_number) +end diff --git a/db/migrate/20170128214244_adds_user_id_to_poll_voters.rb b/db/migrate/20170128214244_adds_user_id_to_poll_voters.rb new file mode 100644 index 000000000..edf635cfc --- /dev/null +++ b/db/migrate/20170128214244_adds_user_id_to_poll_voters.rb @@ -0,0 +1,5 @@ +class AddsUserIdToPollVoters < ActiveRecord::Migration + def change + add_reference :poll_voters, :user, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 290703e9e..d278017c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170125114952) do +ActiveRecord::Schema.define(version: 20170128214244) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -469,11 +469,13 @@ ActiveRecord::Schema.define(version: 20170125114952) do t.string "gender" t.integer "geozone_id" t.integer "answer_id" + t.integer "user_id" end add_index "poll_voters", ["document_number"], name: "index_poll_voters_on_document_number", using: :btree add_index "poll_voters", ["poll_id", "document_number", "document_type"], name: "doc_by_poll", using: :btree add_index "poll_voters", ["poll_id"], name: "index_poll_voters_on_poll_id", using: :btree + add_index "poll_voters", ["user_id"], name: "index_poll_voters_on_user_id", using: :btree create_table "polls", force: :cascade do |t| t.string "name" diff --git a/spec/factories.rb b/spec/factories.rb index 7653f9a3a..c8e504b65 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -22,6 +22,9 @@ FactoryGirl.define do sms_confirmation_code "1234" document_type "1" document_number + date_of_birth Date.new(1980, 12, 31) + gender "female" + geozone end trait :level_three do @@ -37,6 +40,7 @@ FactoryGirl.define do trait :with_confirmed_hide do confirmed_hide_at Time.current end + end factory :identity do @@ -422,6 +426,7 @@ FactoryGirl.define do factory :poll_voter, class: 'Poll::Voter' do poll + association :user, :level_two trait :from_booth do association :booth_assignment, factory: :poll_booth_assignment @@ -451,6 +456,13 @@ FactoryGirl.define do answer { question.valid_answers.sample } end + factory :officing_residence, class: 'Officing::Residence' do + user + document_number + document_type "1" + date_of_birth Date.new(1980, 12, 31) + end + factory :organization do user responsible_name "Johnny Utah" @@ -507,6 +519,10 @@ FactoryGirl.define do sequence(:name) { |n| "District #{n}" } sequence(:external_code) { |n| "#{n}" } sequence(:census_code) { |n| "#{n}" } + + trait :in_census do + census_code "01" + end end factory :banner do diff --git a/spec/features/officing/residence_spec.rb b/spec/features/officing/residence_spec.rb new file mode 100644 index 000000000..bc147a919 --- /dev/null +++ b/spec/features/officing/residence_spec.rb @@ -0,0 +1,50 @@ +require 'rails_helper' + +feature 'Residence' do + let(:officer) { create(:poll_officer) } + + background do + login_as(officer.user) + visit officing_root_path + end + + scenario "Verify voter" do + within("#side_menu") do + click_link "Validate document" + end + + fill_in 'residence_document_number', with: "12345678Z" + select 'DNI', from: 'residence_document_type' + select_date '31-December-1980', from: 'residence_date_of_birth' + + click_button 'Validate document' + + expect(page).to have_content 'Document verified with Census' + end + + scenario "Error on verify" do + within("#side_menu") do + click_link "Validate document" + end + + click_button 'Validate document' + expect(page).to have_content /\d errors? prevented the verification of this document/ + end + + scenario "Error on Census" do + within("#side_menu") do + click_link "Validate document" + end + + fill_in 'residence_document_number', with: "12345678Z" + select 'DNI', from: 'residence_document_type' + select '1997', from: 'residence_date_of_birth_1i' + select 'January', from: 'residence_date_of_birth_2i' + select '1', from: 'residence_date_of_birth_3i' + + click_button 'Validate document' + + expect(page).to have_content 'The Census was unable to verify this document' + end + +end \ No newline at end of file diff --git a/spec/features/officing/voters_spec.rb b/spec/features/officing/voters_spec.rb new file mode 100644 index 000000000..a94c764ec --- /dev/null +++ b/spec/features/officing/voters_spec.rb @@ -0,0 +1,55 @@ +require 'rails_helper' + +feature 'Voters' do + + let(:officer) { create(:poll_officer) } + + background do + login_as(officer.user) + create(:geozone, :in_census) + + #remove once foundation.equalizer js error has been fixed + Capybara.current_driver = :poltergeist_no_js_errors + end + + scenario "Can vote", :js do + poll = create(:poll) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content poll.name + + click_button "Validate vote" + + expect(page).to have_content "Vote validated successfully" + expect(page).to_not have_button "Validate vote" + + page.evaluate_script("window.location.reload()") + expect(page).to have_content "Has already participated in this poll" + expect(page).to_not have_button "Validate vote" + end + + scenario "Already voted", :js do + poll1 = create(:poll) + poll2 = create(:poll) + + user = create(:user, :level_two) + voter = create(:poll_voter, poll: poll1, user: user) + + visit new_officing_voter_path(id: voter.user.id) + + within("#poll_#{poll1.id}") do + expect(page).to have_content "Has already participated in this poll" + expect(page).to_not have_button "Validate vote" + end + + within("#poll_#{poll2.id}") do + expect(page).to have_button "Validate vote" + end + end + + #Fix and use answerable_by(user) + xscenario "Display only answerable polls" +end \ No newline at end of file diff --git a/spec/features/polls/questions_spec.rb b/spec/features/polls/questions_spec.rb index d7d4f8c63..39b60930d 100644 --- a/spec/features/polls/questions_spec.rb +++ b/spec/features/polls/questions_spec.rb @@ -15,6 +15,7 @@ feature 'Poll Questions' do context 'Answering' do let(:geozone) { create(:geozone) } let(:poll) { create(:poll, geozone_restricted: true, geozone_ids: [geozone.id]) } + scenario 'Non-logged in users' do question = create(:poll_question, valid_answers: 'Han Solo, Chewbacca') diff --git a/spec/models/officing/residence_spec.rb b/spec/models/officing/residence_spec.rb new file mode 100644 index 000000000..1f09f8123 --- /dev/null +++ b/spec/models/officing/residence_spec.rb @@ -0,0 +1,87 @@ +require 'rails_helper' + +describe Officing::Residence do + + let!(:geozone) { create(:geozone, census_code: "01") } + let(:residence) { build(:officing_residence, document_number: "12345678Z") } + + describe "validations" do + + it "should be valid" do + expect(residence).to be_valid + end + + describe "dates" do + it "should be valid with a valid date of birth" do + residence = Officing::Residence.new({"date_of_birth(3i)"=>"1", "date_of_birth(2i)"=>"1", "date_of_birth(1i)"=>"1980"}) + expect(residence.errors[:date_of_birth].size).to eq(0) + end + + it "should not be valid without a date of birth" do + residence = Officing::Residence.new({"date_of_birth(3i)"=>"", "date_of_birth(2i)"=>"", "date_of_birth(1i)"=>""}) + expect(residence).to_not be_valid + expect(residence.errors[:date_of_birth]).to include("can't be blank") + end + end + + it "should validate user has allowed age" do + residence = Officing::Residence.new({"date_of_birth(3i)"=>"1", "date_of_birth(2i)"=>"1", "date_of_birth(1i)"=>"#{5.year.ago.year}"}) + expect(residence).to_not be_valid + expect(residence.errors[:date_of_birth]).to include("You don't have the required age to participate") + end + + end + + describe "new" do + it "should upcase document number" do + residence = Officing::Residence.new({document_number: "x1234567z"}) + expect(residence.document_number).to eq("X1234567Z") + end + + it "should remove all characters except numbers and letters" do + residence = Officing::Residence.new({document_number: " 12.345.678 - B"}) + expect(residence.document_number).to eq("12345678B") + end + end + + describe "save" do + + it "should store document number, document type, geozone, date of birth and gender" do + residence.save + user = residence.user + + expect(user.document_number).to eq('12345678Z') + expect(user.document_type).to eq("1") + expect(user.date_of_birth.year).to eq(1980) + expect(user.date_of_birth.month).to eq(12) + expect(user.date_of_birth.day).to eq(31) + expect(user.gender).to eq('male') + expect(user.geozone).to eq(geozone) + end + + it "should find existing user and use demographic information" do + geozone = create(:geozone) + create(:user, document_number: "12345678Z", + document_type: "1", + date_of_birth: Date.new(1981, 11, 30), + gender: 'female', + geozone: geozone) + + residence = build(:officing_residence, + document_number: "12345678Z", + document_type: "1") + + residence.save + user = residence.user + + expect(user.document_number).to eq('12345678Z') + expect(user.document_type).to eq("1") + expect(user.date_of_birth.year).to eq(1981) + expect(user.date_of_birth.month).to eq(11) + expect(user.date_of_birth.day).to eq(30) + expect(user.gender).to eq('female') + expect(user.geozone).to eq(geozone) + end + + end +end \ No newline at end of file diff --git a/spec/models/poll/voter_spec.rb b/spec/models/poll/voter_spec.rb index 88541dc82..ab66d3b76 100644 --- a/spec/models/poll/voter_spec.rb +++ b/spec/models/poll/voter_spec.rb @@ -5,9 +5,29 @@ describe :voter do let(:poll) { create(:poll) } let(:booth) { create(:poll_booth) } let(:booth_assignment) { create(:poll_booth_assignment, poll: poll, booth: booth) } + let(:voter) { create(:poll_voter) } describe "validations" do + it "should be valid" do + expect(voter).to be_valid + end + + it "should not be valid without a user" do + voter.user = nil + expect(voter).to_not be_valid + end + + it "should not be valid without a poll" do + voter.poll = nil + expect(voter).to_not be_valid + end + + it "should not be valid without a geozone" do + voter.user.geozone = nil + expect(voter).to_not be_valid + end + it "should be valid if has not voted" do voter = build(:poll_voter, :valid_document) @@ -61,4 +81,31 @@ describe :voter do end end + + describe "save" do + + it "sets demographic info" do + geozone = create(:geozone) + user = create(:user, + geozone: geozone, + date_of_birth: 30.years.ago, + gender: "female") + + voter = build(:poll_voter, user: user) + voter.save + + expect(voter.geozone).to eq(geozone) + expect(voter.age).to eq(30) + expect(voter.gender).to eq("female") + end + + it "sets user info" do + user = create(:user, document_number: "1234A", document_type: "1") + voter = build(:poll_voter, user: user) + voter.save + + expect(voter.document_number).to eq("1234A") + expect(voter.document_type).to eq("1") + end + end end \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a40934d92..97a94bec7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -105,4 +105,9 @@ RSpec.configure do |config| end # Parallel build helper configuration for travis -Knapsack::Adapters::RSpecAdapter.bind \ No newline at end of file +Knapsack::Adapters::RSpecAdapter.bind + +options = {js_errors: false} +Capybara.register_driver :poltergeist_no_js_errors do |app| + Capybara::Poltergeist::Driver.new(app, options) +end \ No newline at end of file diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index 1e317909b..008403dbe 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -141,6 +141,16 @@ module CommonActions expect(page).to have_content 'Residence verified' end + def officing_verify_residence + fill_in 'residence_document_number', with: "12345678Z" + select 'DNI', from: 'residence_document_type' + select_date '31-December-1980', from: 'residence_date_of_birth' + + click_button 'Validate document' + + expect(page).to have_content 'Document verified with Census' + end + def confirm_phone fill_in 'sms_phone', with: "611111111" click_button 'Send' From c74587d9215dea7b5d07bb370560c7c57c37f8e2 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 29 Jan 2017 03:02:13 +0100 Subject: [PATCH 290/523] fixes specs --- config/locales/officing.en.yml | 7 ----- config/locales/officing.es.yml | 7 ----- spec/factories.rb | 2 +- spec/features/moderation/comments_spec.rb | 2 ++ spec/features/moderation/debates_spec.rb | 2 ++ spec/features/moderation/proposals_spec.rb | 2 ++ .../valuation/budget_investments_spec.rb | 2 ++ .../valuation/spending_proposals_spec.rb | 2 ++ spec/models/poll/poll_spec.rb | 1 + spec/models/poll/voter_spec.rb | 26 ++++++++++++------- 10 files changed, 29 insertions(+), 24 deletions(-) diff --git a/config/locales/officing.en.yml b/config/locales/officing.en.yml index 2d8d77e13..54ac52edf 100644 --- a/config/locales/officing.en.yml +++ b/config/locales/officing.en.yml @@ -35,21 +35,14 @@ en: new: title: Validate document document_number: Document number - document_type: - passport: Passport - residence_card: Residence card - spanish_id: DNI document_type_label: Document type submit: Validate document error_verifying_census: "The Census was unable to verify this document." - error_not_allowed_age: You don't have the required age to participate - error_verifying_census_offices: Citizen Support Office form_errors: prevented the verification of this document voters: new: title: Polls show: - title: Validate document error_already_voted: Has already participated in this poll submit: Validate vote success: Vote validated successfully. diff --git a/config/locales/officing.es.yml b/config/locales/officing.es.yml index 827aea9d5..0aa1b419c 100644 --- a/config/locales/officing.es.yml +++ b/config/locales/officing.es.yml @@ -35,21 +35,14 @@ es: new: title: Validar documento document_number: Número de documento - document_type: - passport: Pasaporte - residence_card: Tarjeta de residencia - spanish_id: DNI document_type_label: Tipo de documento submit: Validar documento - error_not_allowed_age: No tienes la edad mínima para participar error_verifying_census: El Padrón no pudo verificar este documento. form_errors: evitaron verificar este documento voters: new: title: Votaciones show: - title: Validar documento error_already_voted: "Ya ha participado en la votación." - can_participate: "La persona asociada al documento puede participar en la votación." submit: Validar voto success: Voto validado correctamente. diff --git a/spec/factories.rb b/spec/factories.rb index c8e504b65..dc3b4ff58 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -445,7 +445,7 @@ FactoryGirl.define do factory :poll_answer, class: 'Poll::Answer' do association :question, factory: :poll_question - association :author, factory: [:user, :level_three] + association :author, factory: [:user, :level_two] answer { question.valid_answers.sample } end diff --git a/spec/features/moderation/comments_spec.rb b/spec/features/moderation/comments_spec.rb index dc3604c3a..65d2481ba 100644 --- a/spec/features/moderation/comments_spec.rb +++ b/spec/features/moderation/comments_spec.rb @@ -84,6 +84,8 @@ feature 'Moderate comments' do end scenario "select all/none", :js do + Capybara.current_driver = :poltergeist_no_js_errors + create_list(:comment, 2) visit moderation_comments_path diff --git a/spec/features/moderation/debates_spec.rb b/spec/features/moderation/debates_spec.rb index 78aca9b7e..8a729efe7 100644 --- a/spec/features/moderation/debates_spec.rb +++ b/spec/features/moderation/debates_spec.rb @@ -91,6 +91,8 @@ feature 'Moderate debates' do end scenario "select all/none", :js do + Capybara.current_driver = :poltergeist_no_js_errors + create_list(:debate, 2) visit moderation_debates_path diff --git a/spec/features/moderation/proposals_spec.rb b/spec/features/moderation/proposals_spec.rb index ab8da4764..6acff7c71 100644 --- a/spec/features/moderation/proposals_spec.rb +++ b/spec/features/moderation/proposals_spec.rb @@ -83,6 +83,8 @@ feature 'Moderate proposals' do end scenario "select all/none", :js do + Capybara.current_driver = :poltergeist_no_js_errors + create_list(:proposal, 2) visit moderation_proposals_path diff --git a/spec/features/valuation/budget_investments_spec.rb b/spec/features/valuation/budget_investments_spec.rb index bac7d1fe2..a3f5a1705 100644 --- a/spec/features/valuation/budget_investments_spec.rb +++ b/spec/features/valuation/budget_investments_spec.rb @@ -55,6 +55,8 @@ feature 'Valuation budget investments' do end scenario "Index filtering by heading", :js do + Capybara.current_driver = :poltergeist_no_js_errors + group = create(:budget_group, budget: @budget) heading1 = create(:budget_heading, name: "District 9", group: group) heading2 = create(:budget_heading, name: "Down to the river", group: group) diff --git a/spec/features/valuation/spending_proposals_spec.rb b/spec/features/valuation/spending_proposals_spec.rb index 25c5dfa61..035ed59fd 100644 --- a/spec/features/valuation/spending_proposals_spec.rb +++ b/spec/features/valuation/spending_proposals_spec.rb @@ -83,6 +83,8 @@ feature 'Valuation spending proposals' do end scenario "Index filtering by geozone", :js do + Capybara.current_driver = :poltergeist_no_js_errors + geozone = create(:geozone, name: "District 9") spending_proposal1 = create(:spending_proposal, title: "Realocate visitors", geozone: geozone) spending_proposal2 = create(:spending_proposal, title: "Destroy the city") diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index b2ec29e5c..b0bf923c0 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -64,6 +64,7 @@ describe :poll do describe "#document_has_voted?" do it "returns true if Poll::Voter with document exists" do + poll = create(:poll) voter = create(:poll_voter, :valid_document, poll: poll) expect(poll.document_has_voted?(voter.document_number, voter.document_type)).to eq(true) diff --git a/spec/models/poll/voter_spec.rb b/spec/models/poll/voter_spec.rb index ab66d3b76..0770c5654 100644 --- a/spec/models/poll/voter_spec.rb +++ b/spec/models/poll/voter_spec.rb @@ -35,16 +35,20 @@ describe :voter do end it "should not be valid if the user has already voted in the same poll or booth_assignment" do - voter1 = create(:poll_voter, :valid_document, poll: poll) - voter2 = build(:poll_voter, :valid_document, poll: poll) + user = create(:user, :level_two) + + voter1 = create(:poll_voter, user: user, poll: poll) + voter2 = build(:poll_voter, user: user, poll: poll) expect(voter2).to_not be_valid expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"]) end it "should not be valid if the user has already voted in the same poll/booth" do - voter1 = create(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment) - voter2 = build(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment) + user = create(:user, :level_two) + + voter1 = create(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment) + voter2 = build(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment) expect(voter2).to_not be_valid expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"]) @@ -54,8 +58,10 @@ describe :voter do booth_assignment1 = create(:poll_booth_assignment, poll: poll) booth_assignment2 = create(:poll_booth_assignment, poll: poll) - voter1 = create(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment1) - voter2 = build(:poll_voter, :valid_document, poll: poll, booth_assignment: booth_assignment2) + user = create(:user, :level_two) + + voter1 = create(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment1) + voter2 = build(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment2) expect(voter2).to_not be_valid expect(voter2.errors.messages[:document_number]).to eq(["User has already voted"]) @@ -65,8 +71,10 @@ describe :voter do booth_assignment1 = create(:poll_booth_assignment, booth: booth) booth_assignment2 = create(:poll_booth_assignment, booth: booth, poll: poll) - voter1 = create(:poll_voter, :valid_document, booth_assignment: booth_assignment1) - voter2 = build(:poll_voter, :valid_document, booth_assignment: booth_assignment2) + user = create(:user, :level_two) + + voter1 = create(:poll_voter, user: user, booth_assignment: booth_assignment1) + voter2 = build(:poll_voter, user: user, booth_assignment: booth_assignment2) expect(voter2).to be_valid end @@ -75,7 +83,7 @@ describe :voter do answer = create(:poll_answer) answer.record_voter_participation - voter = build(:poll_voter, poll: answer.question.poll, document_number: answer.author.document_number, document_type: "1") + voter = build(:poll_voter, poll: answer.question.poll, user: answer.author) expect(voter).to_not be_valid expect(voter.errors.messages[:document_number]).to eq(["User has already voted"]) end From 5d13bdc15dd65fce32ec2cdf95a96a0db2a415b1 Mon Sep 17 00:00:00 2001 From: kikito Date: Sun, 29 Jan 2017 22:25:10 +0100 Subject: [PATCH 291/523] Removes 'manage' from admin permissions in Polls --- app/models/abilities/administrator.rb | 4 ++-- spec/features/admin/poll/booth_assigments_spec.rb | 3 ++- spec/models/abilities/administrator_spec.rb | 3 --- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index a45eef73e..34adac19b 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -53,8 +53,8 @@ module Abilities can [:index, :create, :edit, :update, :destroy], Geozone - can [:manage], Poll - can [:manage], Poll::Booth + can [:read, :create, :update, :destroy, :add_question, :remove_question, :search_booths, :search_questions, :search_officers], Poll + can [:read, :create, :update, :destroy], Poll::Booth can [:search, :create, :index, :destroy], ::Poll::Officer can [:create, :destroy], ::Poll::BoothAssignment can [:create, :destroy], ::Poll::OfficerAssignment diff --git a/spec/features/admin/poll/booth_assigments_spec.rb b/spec/features/admin/poll/booth_assigments_spec.rb index 28d612257..14a8ba1e1 100644 --- a/spec/features/admin/poll/booth_assigments_spec.rb +++ b/spec/features/admin/poll/booth_assigments_spec.rb @@ -20,6 +20,7 @@ feature 'Admin booths assignments' do fill_in 'search-booths', with: booth.name click_button 'Search' + expect(page).to have_content(booth.name) within('#search-booths-results') do click_link 'Assign booth' @@ -167,4 +168,4 @@ feature 'Admin booths assignments' do end end -end \ No newline at end of file +end diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb index c368667dd..5312221b8 100644 --- a/spec/models/abilities/administrator_spec.rb +++ b/spec/models/abilities/administrator_spec.rb @@ -57,9 +57,6 @@ describe "Abilities::Administrator" do it { should be_able_to(:valuate, SpendingProposal) } it { should be_able_to(:destroy, SpendingProposal) } - it { should be_able_to(:manage, Poll) } - it { should be_able_to(:manage, Poll::Booth) } - it { should be_able_to(:create, Budget) } it { should be_able_to(:update, Budget) } From e39447063495a824dd173638e89acae1a23e19aa Mon Sep 17 00:00:00 2001 From: kikito Date: Sun, 29 Jan 2017 22:52:13 +0100 Subject: [PATCH 292/523] Improves order of polls when listing them in index --- app/models/poll.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index c5da9dcd0..1ac73e837 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -18,7 +18,7 @@ class Poll < ActiveRecord::Base scope :published, -> { where('published = ?', true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } - scope :sort_for_list, -> { order(:starts_at) } + scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) } def current?(timestamp = DateTime.current) starts_at <= timestamp && timestamp <= ends_at From 55ace74c674d409c0ee6f7623b8cce1401bde6f2 Mon Sep 17 00:00:00 2001 From: kikito Date: Sun, 29 Jan 2017 22:53:05 +0100 Subject: [PATCH 293/523] Shows geozones when listing polls --- app/controllers/polls_controller.rb | 2 +- app/views/polls/index.html.erb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index ce80f8dcc..b77ac22ea 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -5,7 +5,7 @@ class PollsController < ApplicationController has_filters %w{current expired incoming} def index - @polls = @polls.send(@current_filter).sort_for_list.page(params[:page]) + @polls = @polls.send(@current_filter).includes(:geozones).sort_for_list.page(params[:page]) end def show diff --git a/app/views/polls/index.html.erb b/app/views/polls/index.html.erb index bba805ebb..ad37e4687 100644 --- a/app/views/polls/index.html.erb +++ b/app/views/polls/index.html.erb @@ -21,6 +21,11 @@

      <%= poll.name %>

      <%= poll_dates(poll) %>

      +
        + <% poll.geozones.each do |g| %> +
      • <%= g.name %>
      • + <% end %> +
      <%= link_to t("polls.index.button"), From 964da1e6d687d973bf66adebdf8f8f44cdd6e76e Mon Sep 17 00:00:00 2001 From: kikito Date: Sun, 29 Jan 2017 22:53:32 +0100 Subject: [PATCH 294/523] Fixes rails autoloader error in development --- app/controllers/polls_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index b77ac22ea..41a038b46 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -4,6 +4,8 @@ class PollsController < ApplicationController has_filters %w{current expired incoming} + ::Poll::Answer # trigger autoload + def index @polls = @polls.send(@current_filter).includes(:geozones).sort_for_list.page(params[:page]) end @@ -12,7 +14,7 @@ class PollsController < ApplicationController @questions = @poll.questions.for_render.sort_for_list @answers_by_question_id = {} - poll_answers = Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id)) + poll_answers = ::Poll::Answer.by_question(@poll.question_ids).by_author(current_user.try(:id)) poll_answers.each do |answer| @answers_by_question_id[answer.question_id] = answer.answer end From b2a43d84504f1fbeddedc62893e66dffe5852058 Mon Sep 17 00:00:00 2001 From: kikito Date: Sun, 29 Jan 2017 22:53:58 +0100 Subject: [PATCH 295/523] Extracts list of reasons to a partial --- .../polls/_reasons_for_not_answering.html.erb | 24 ++++++++++++++++++ app/views/polls/questions/show.html.erb | 25 +------------------ 2 files changed, 25 insertions(+), 24 deletions(-) create mode 100644 app/views/polls/_reasons_for_not_answering.html.erb diff --git a/app/views/polls/_reasons_for_not_answering.html.erb b/app/views/polls/_reasons_for_not_answering.html.erb new file mode 100644 index 000000000..374d319d9 --- /dev/null +++ b/app/views/polls/_reasons_for_not_answering.html.erb @@ -0,0 +1,24 @@ +<% if poll.incoming? %> +
      + <%= t('poll_questions.show.cant_answer_incoming') %> +
      +<% elsif poll.expired? %> +
      + <%= t('poll_questions.show.cant_answer_expired') %> +
      +<% elsif current_user.nil? %> +
      + <%= t("poll_questions.show.not_logged_in", + signin: link_to(t("poll_questions.show.signin"), new_user_session_path, class: "probe-message"), + signup: link_to(t("poll_questions.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> +
      +<% elsif current_user.unverified? %> +
      + <%= t('poll_questions.show.cant_answer_verify_html', + verify_link: link_to(t('poll_questions.show.verify_link'), verification_path)) %> +
      +<% else %> +
      + <%= t('poll_questions.show.cant_answer_wrong_geozone') %> +
      +<% end %> diff --git a/app/views/polls/questions/show.html.erb b/app/views/polls/questions/show.html.erb index c04490f7d..f743d89a9 100644 --- a/app/views/polls/questions/show.html.erb +++ b/app/views/polls/questions/show.html.erb @@ -54,30 +54,7 @@ %>
      <% else %> - <% if @question.poll.incoming? %> -
      - <%= t('poll_questions.show.cant_answer_incoming') %> -
      - <% elsif @question.poll.expired? %> -
      - <%= t('poll_questions.show.cant_answer_expired') %> -
      - <% elsif current_user.nil? %> -
      - <%= t("poll_questions.show.not_logged_in", - signin: link_to(t("poll_questions.show.signin"), new_user_session_path, class: "probe-message"), - signup: link_to(t("poll_questions.show.signup"), new_user_registration_path, class: "probe-message")).html_safe %> -
      - <% elsif current_user.unverified? %> -
      - <%= t('poll_questions.show.cant_answer_verify_html', - verify_link: link_to(t('poll_questions.show.verify_link'), verification_path)) %> -
      - <% else %> -
      - <%= t('poll_questions.show.cant_answer_wrong_geozone') %> -
      - <% end %> + <%= render 'polls/reasons_for_not_answering', poll: @question.poll %>
      From c1345a1f7d21e0e0739c4c1e14f26be2bc4abe92 Mon Sep 17 00:00:00 2001 From: kikito Date: Sun, 29 Jan 2017 22:54:30 +0100 Subject: [PATCH 296/523] Includes reason for not being able to participate in poll index --- app/views/polls/index.html.erb | 10 ++++++---- config/locales/en.yml | 3 ++- config/locales/es.yml | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/views/polls/index.html.erb b/app/views/polls/index.html.erb index ad37e4687..e23fc81ee 100644 --- a/app/views/polls/index.html.erb +++ b/app/views/polls/index.html.erb @@ -28,10 +28,12 @@
    - <%= link_to t("polls.index.button"), - poll, - class: "button", - title: t("polls.index.button") + ": " + (poll.name) %> + <% if can? :answer, poll %> + <%= link_to t("polls.index.participate_button"), poll, class: "button" %> + <% else %> + <%= render 'polls/reasons_for_not_answering', poll: poll %> + <%= link_to t("polls.index.view_button"), poll, class: "button info small" %> + <% end %>
    diff --git a/config/locales/en.yml b/config/locales/en.yml index b778c4166..a5b671809 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -401,7 +401,8 @@ en: incoming: "Incoming" expired: "Expired" title: "Polls" - button: "Participate in this poll" + participate_button: "Participate in this poll" + view_button: "View details about this poll" show: dates_title: "Participation dates" cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate." diff --git a/config/locales/es.yml b/config/locales/es.yml index abbe23ddf..388cbbbe7 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -401,7 +401,8 @@ es: incoming: "Próximamente" expired: "Terminadas" title: "Votaciones" - button: "Participar en esta votación" + participate_button: "Participar en esta votación" + view_button: "Ver detalles de la votación" show: dates_title: "Fechas de participación" cant_answer_not_logged_in: "Necesitas %{signin} o %{signup} para participar." From 01039c00e394be44deddd7b3151d3a66bee8cb4f Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 30 Jan 2017 12:58:02 +0100 Subject: [PATCH 297/523] fixes failing spec --- spec/features/polls/polls_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index fe5957181..7293d6682 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -11,7 +11,7 @@ feature 'Polls' do polls.each do |poll| expect(page).to have_content(poll.name) - expect(page).to have_link("Participate in this poll") + expect(page).to have_link("View details about this poll") end end From 1977b23803eff41738d89791272463c1063492c6 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 30 Jan 2017 13:33:38 +0100 Subject: [PATCH 298/523] updates styles and i18n for officing views --- app/views/officing/residence/new.html.erb | 27 +++++++------- .../officing/voters/_already_voted.html.erb | 2 +- app/views/officing/voters/new.html.erb | 37 +++++++++++++------ config/locales/activemodel.en.yml | 6 ++- config/locales/activemodel.es.yml | 6 ++- config/locales/officing.en.yml | 5 ++- config/locales/officing.es.yml | 7 ++-- 7 files changed, 58 insertions(+), 32 deletions(-) diff --git a/app/views/officing/residence/new.html.erb b/app/views/officing/residence/new.html.erb index 45290762e..4d15db993 100644 --- a/app/views/officing/residence/new.html.erb +++ b/app/views/officing/residence/new.html.erb @@ -1,26 +1,27 @@

    <%= t("officing.residence.new.title") %>

    -
    -
    +