From c9b8a58e3fa1cc211f76f73af4f2e66684733b3f Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 14 Sep 2016 13:53:35 +0200 Subject: [PATCH 001/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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/613] 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 98db33f6234fc96d0bb8e5e0f3cc6d344bfc2faf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Miedes=20Garc=C3=A9s?= Date: Thu, 5 Jan 2017 23:31:11 +0100 Subject: [PATCH 248/613] Track email digests --- ...15410_add_failed_email_digests_count_to_users.rb | 5 +++++ db/schema.rb | 9 ++++++--- lib/email_digest.rb | 1 + lib/tasks/emails.rake | 9 +++++++-- spec/lib/email_digests_spec.rb | 13 +++++++++++++ 5 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20170105215410_add_failed_email_digests_count_to_users.rb diff --git a/db/migrate/20170105215410_add_failed_email_digests_count_to_users.rb b/db/migrate/20170105215410_add_failed_email_digests_count_to_users.rb new file mode 100644 index 000000000..44744ed98 --- /dev/null +++ b/db/migrate/20170105215410_add_failed_email_digests_count_to_users.rb @@ -0,0 +1,5 @@ +class AddFailedEmailDigestsCountToUsers < ActiveRecord::Migration + def change + add_column :users, :failed_email_digests_count, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 0c3cfd3cf..8195aa0cf 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: 20170105215410) 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 @@ -145,6 +145,7 @@ ActiveRecord::Schema.define(version: 20161229110336) do add_index "debates", ["cached_votes_total"], name: "index_debates_on_cached_votes_total", using: :btree add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree add_index "debates", ["confidence_score"], name: "index_debates_on_confidence_score", using: :btree + add_index "debates", ["description"], name: "index_debates_on_description", using: :btree add_index "debates", ["geozone_id"], name: "index_debates_on_geozone_id", using: :btree add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree add_index "debates", ["hot_score"], name: "index_debates_on_hot_score", using: :btree @@ -308,6 +309,7 @@ ActiveRecord::Schema.define(version: 20161229110336) do add_index "proposals", ["author_id"], name: "index_proposals_on_author_id", using: :btree add_index "proposals", ["cached_votes_up"], name: "index_proposals_on_cached_votes_up", using: :btree add_index "proposals", ["confidence_score"], name: "index_proposals_on_confidence_score", using: :btree + add_index "proposals", ["description"], name: "index_proposals_on_description", using: :btree add_index "proposals", ["geozone_id"], name: "index_proposals_on_geozone_id", using: :btree add_index "proposals", ["hidden_at"], name: "index_proposals_on_hidden_at", using: :btree add_index "proposals", ["hot_score"], name: "index_proposals_on_hot_score", using: :btree @@ -480,8 +482,9 @@ 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-02 13:51:14', null: false t.boolean "created_from_signature", default: false + t.integer "failed_email_digests_count", default: 0 end add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree diff --git a/lib/email_digest.rb b/lib/email_digest.rb index 2936a5db5..511d137a6 100644 --- a/lib/email_digest.rb +++ b/lib/email_digest.rb @@ -22,6 +22,7 @@ class EmailDigest def mark_as_emailed notifications.update_all(emailed_at: Time.current) + user.update(failed_email_digests_count: 0) end end diff --git a/lib/tasks/emails.rake b/lib/tasks/emails.rake index ffadebf05..3afa81449 100644 --- a/lib/tasks/emails.rake +++ b/lib/tasks/emails.rake @@ -4,8 +4,13 @@ namespace :emails do task digest: :environment do User.email_digest.find_each do |user| email_digest = EmailDigest.new(user) - email_digest.deliver - email_digest.mark_as_emailed + begin + email_digest.deliver + email_digest.mark_as_emailed + rescue + user.increment_counter(:failed_email_digests_count) + user.save + end end end diff --git a/spec/lib/email_digests_spec.rb b/spec/lib/email_digests_spec.rb index 76efffe2e..6f15a92d4 100644 --- a/spec/lib/email_digests_spec.rb +++ b/spec/lib/email_digests_spec.rb @@ -122,6 +122,19 @@ describe EmailDigest do expect(notification3.emailed_at).to_not be end + it "resets the failed_email_digests_count flag" do + user1 = create(:user, failed_email_digests_count: 0) + user2 = create(:user, failed_email_digests_count: 3) + + email_digest_1 = EmailDigest.new(user1) + email_digest_2 = EmailDigest.new(user2) + email_digest_1.mark_as_emailed + email_digest_2.mark_as_emailed + + expect(user1.failed_email_digests_count).to eq(0) + expect(user2.failed_email_digests_count).to eq(0) + end + end end From d30c97c0c24e2524fc79123de9e3e76640e6f67a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 19 Jan 2017 18:04:04 +0100 Subject: [PATCH 249/613] 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 250/613] 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 251/613] 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 252/613] 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 253/613] 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 254/613] 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 255/613] 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 256/613] 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 257/613] 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 258/613] 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 259/613] 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 260/613] 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 261/613] 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 262/613] 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 263/613] 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 264/613] 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 265/613] 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 266/613] 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 267/613] 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 268/613] 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 269/613] 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 270/613] 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 271/613] 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 272/613] 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 273/613] 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 274/613] 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 275/613] 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 276/613] 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 277/613] 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 278/613] 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 279/613] 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 280/613] 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 281/613] 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 b1a5a324c7c48c53919407c7a7aae80f159c7e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 26 Jan 2017 13:15:43 +0100 Subject: [PATCH 282/613] adds missing checkbox label for unfeasible investments --- app/views/admin/shared/_budget_investment_search.html.erb | 1 + config/locales/admin.en.yml | 1 + config/locales/admin.es.yml | 1 + 3 files changed, 3 insertions(+) diff --git a/app/views/admin/shared/_budget_investment_search.html.erb b/app/views/admin/shared/_budget_investment_search.html.erb index 410044c10..f29a3a0d1 100644 --- a/app/views/admin/shared/_budget_investment_search.html.erb +++ b/app/views/admin/shared/_budget_investment_search.html.erb @@ -14,6 +14,7 @@
    <%= check_box_tag :unfeasible, "1", params[:unfeasible].present? %> + <%= t("admin.budget_investments.search_unfeasible") %>
    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index dadcb7745..460319748 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -153,6 +153,7 @@ en: tags: Tags tags_placeholder: "Write the tags you want separated by commas (,)" undefined: Undefined + search_unfeasible: Search unfeasible comments: index: filter: Filter diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 09959cfde..7d6438416 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -153,6 +153,7 @@ es: tags: Etiquetas tags_placeholder: "Escribe las etiquetas que desees separadas por comas (,)" undefined: Sin definir + search_unfeasible: Buscar inviables comments: index: filter: Filtro 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 283/613] 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 284/613] 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 285/613] 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 286/613] 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 287/613] 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 288/613] 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 289/613] 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 290/613] 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 291/613] 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 292/613] 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 293/613] 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 294/613] 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 295/613] 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 296/613] 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 297/613] 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 298/613] 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 299/613] 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 300/613] 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") %>

    -
    -
    + diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 6209805cf..869417777 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -128,6 +128,7 @@ <% if browser.device.mobile? %> + <%= t("social_share_button.whatsapp") %> <% end %>
    diff --git a/app/views/spending_proposals/show.html.erb b/app/views/spending_proposals/show.html.erb index 0da045860..96468eb4c 100644 --- a/app/views/spending_proposals/show.html.erb +++ b/app/views/spending_proposals/show.html.erb @@ -47,6 +47,7 @@ <% if browser.device.mobile? %> + <%= t("social_share_button.whatsapp") %> <% end %>
    diff --git a/config/locales/social_share_button.en.yml b/config/locales/social_share_button.en.yml index b06cb5ad3..a4ba5436f 100644 --- a/config/locales/social_share_button.en.yml +++ b/config/locales/social_share_button.en.yml @@ -17,3 +17,4 @@ en: plurk: "Plurk" pinterest: "Pinterest" email: "Email" + whatsapp: "WhatsApp" \ No newline at end of file diff --git a/config/locales/social_share_button.es.yml b/config/locales/social_share_button.es.yml index 45e4ab2a5..4647fc010 100644 --- a/config/locales/social_share_button.es.yml +++ b/config/locales/social_share_button.es.yml @@ -17,3 +17,4 @@ es: plurk: "Plurk" pinterest: "Pinterest" email: "Correo electrónico" + whatsapp: "WhatsApp" \ No newline at end of file From ad9d6d0713ddc3ce38cee6903827fce14c874ecd Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 6 Mar 2017 13:31:18 +0100 Subject: [PATCH 452/613] fixes tabs role on proposals show --- app/views/proposals/_filter_subnav.html.erb | 2 +- app/views/proposals/show.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/proposals/_filter_subnav.html.erb b/app/views/proposals/_filter_subnav.html.erb index fe875c9a9..6347d56b0 100644 --- a/app/views/proposals/_filter_subnav.html.erb +++ b/app/views/proposals/_filter_subnav.html.erb @@ -1,6 +1,6 @@
    -
      +
      • <%= link_to "#tab-comments" do %>

        diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 869417777..22d17d29f 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -137,7 +137,7 @@

    <% end %> -
    +
    <%= render "proposals/filter_subnav" %> <%= render "proposals/notifications" %> From 5cf9a98e6a79f0251eaf115880880250cdc3ccf4 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 6 Mar 2017 13:38:40 +0100 Subject: [PATCH 453/613] adds lang attribute on error pages --- public/404.html | 2 +- public/422.html | 2 +- public/500.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/public/404.html b/public/404.html index cc6820bba..5b5362192 100644 --- a/public/404.html +++ b/public/404.html @@ -1,5 +1,5 @@ - + Error 404 | Not found diff --git a/public/422.html b/public/422.html index e68d2956f..cca90e5a3 100644 --- a/public/422.html +++ b/public/422.html @@ -1,5 +1,5 @@ - + Error 422 | The change you wanted was rejected diff --git a/public/500.html b/public/500.html index 71978cdce..0b563452a 100644 --- a/public/500.html +++ b/public/500.html @@ -1,5 +1,5 @@ - + Error 500 | Internal server error From 24920e73f6538a807b93ba4497795c3fc47170eb Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 6 Mar 2017 13:42:52 +0100 Subject: [PATCH 454/613] Adds permissions for authors to destroy budget investments --- app/models/abilities/common.rb | 1 + spec/models/abilities/common_spec.rb | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index e324540d2..7ac6a12f4 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -46,6 +46,7 @@ module Abilities can :create, SpendingProposal can :create, Budget::Investment, budget: { phase: "accepting" } + can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id can :vote, Budget::Investment, budget: { phase: "selecting" } can [:show, :create], Budget::Ballot, budget: { phase: "balloting" } can [:create, :destroy], Budget::Ballot::Line, budget: { phase: "balloting" } diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index ce90ab967..f82bcc839 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -10,12 +10,18 @@ describe "Abilities::Common" do let(:comment) { create(:comment) } let(:proposal) { create(:proposal) } let(:accepting_budget) { create(:budget, phase: 'accepting') } + let(:reviewing_budget) { create(:budget, phase: 'reviewing') } let(:selecting_budget) { create(:budget, phase: 'selecting') } let(:balloting_budget) { create(:budget, phase: 'balloting') } let(:investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget) } + let(:investment_in_reviewing_budget) { create(:budget_investment, budget: reviewing_budget) } let(:investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget) } let(:investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget) } + let(:own_investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget, author: user) } + let(:own_investment_in_reviewing_budget) { create(:budget_investment, budget: reviewing_budget, author: user) } + let(:own_investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget, author: user) } + let(:own_investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget, author: user) } let(:ballot_in_accepting_budget) { create(:budget_ballot, budget: accepting_budget) } let(:ballot_in_selecting_budget) { create(:budget_ballot, budget: selecting_budget) } let(:ballot_in_balloting_budget) { create(:budget_ballot, budget: balloting_budget) } @@ -117,6 +123,16 @@ describe "Abilities::Common" do it { should be_able_to(:vote, investment_in_selecting_budget) } it { should_not be_able_to(:vote, investment_in_balloting_budget) } + it { should_not be_able_to(:destroy, investment_in_accepting_budget) } + it { should_not be_able_to(:destroy, investment_in_reviewing_budget) } + it { should_not be_able_to(:destroy, investment_in_selecting_budget) } + it { should_not be_able_to(:destroy, investment_in_balloting_budget) } + + it { should be_able_to(:destroy, own_investment_in_accepting_budget) } + it { should be_able_to(:destroy, own_investment_in_reviewing_budget) } + it { should_not be_able_to(:destroy, own_investment_in_selecting_budget) } + it { should_not be_able_to(:destroy, investment_in_balloting_budget) } + it { should_not be_able_to(:create, ballot_in_accepting_budget) } it { should_not be_able_to(:create, ballot_in_selecting_budget) } it { should be_able_to(:create, ballot_in_balloting_budget) } From 737d347c4a3f0de76c6de8fb723eacccbea1e5d1 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 6 Mar 2017 13:45:11 +0100 Subject: [PATCH 455/613] changes alt text of header logo --- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- config/locales/fr.yml | 2 +- config/locales/pt-BR.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index dd9624188..b09ab94cd 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -195,7 +195,7 @@ en: external_link_transparency: Transparency external_link_transparency_url: https://transparency.consul locale: 'Language:' - logo: Consul + logo: Consul logo management: Management moderation: Moderation valuation: Valuation diff --git a/config/locales/es.yml b/config/locales/es.yml index 0b8fa4b1c..7f8164335 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -195,7 +195,7 @@ es: external_link_transparency: Transparencia external_link_transparency_url: https://transparency.consul locale: 'Idioma:' - logo: Consul + logo: Consul logo management: Gestión moderation: Moderar valuation: Evaluación diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 596531c0d..cc0b1c590 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -874,7 +874,7 @@ fr: external_link_transparency: Transparence external_link_transparency_url: https://transparency.consul locale: 'Langue :' - logo: Consul + logo: Consul logo moderation: Modération more_information: Plus d'information my_account_link: Mon compte diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 75e7aebb6..febe0ed5c 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -860,7 +860,7 @@ pt-BR: external_link_transparency: Transparência external_link_transparency_url: https://transparency.consul locale: 'Idioma:' - logo: Consul + logo: Consul logotipo moderation: Moderação more_information: Mais informações my_account_link: Minha conta From 1e3ea14c9939d5ef950f85cf2c59be28eb105d4a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 6 Mar 2017 14:00:08 +0100 Subject: [PATCH 456/613] improves color contrast on hollow buttons --- app/assets/stylesheets/layout.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 7c3300fa3..1511910b1 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -70,6 +70,11 @@ a { } } +.button.hollow { + border: 1px solid $link; + color: $link; +} + .postfix.button { padding: 0; } From b5fd8cc8b293d52d29b52ffc8156537352031da0 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 6 Mar 2017 14:04:17 +0100 Subject: [PATCH 457/613] fixes missing i18n --- app/views/budgets/investments/_investment_show.html.erb | 2 +- app/views/debates/show.html.erb | 2 +- app/views/proposals/show.html.erb | 2 +- app/views/spending_proposals/show.html.erb | 2 +- config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/locales/social_share_button.en.yml | 3 +-- config/locales/social_share_button.es.yml | 3 +-- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index 37ddc8930..ebac39186 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -105,7 +105,7 @@ <% if browser.device.mobile? %> - <%= t("social_share_button.whatsapp") %> + <%= t("social.whatsapp") %> <% end %>
    diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb index f28691727..096369bc3 100644 --- a/app/views/debates/show.html.erb +++ b/app/views/debates/show.html.erb @@ -55,7 +55,7 @@ <% if browser.device.mobile? %> - <%= t("social_share_button.whatsapp") %> + <%= t("social.whatsapp") %> <% end %>
    diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 22d17d29f..5d184088d 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -128,7 +128,7 @@ <% if browser.device.mobile? %> - <%= t("social_share_button.whatsapp") %> + <%= t("social.whatsapp") %> <% end %>
    diff --git a/app/views/spending_proposals/show.html.erb b/app/views/spending_proposals/show.html.erb index 96468eb4c..4cdfb688b 100644 --- a/app/views/spending_proposals/show.html.erb +++ b/app/views/spending_proposals/show.html.erb @@ -47,7 +47,7 @@ <% if browser.device.mobile? %> - <%= t("social_share_button.whatsapp") %> + <%= t("social.whatsapp") %> <% end %>
    diff --git a/config/locales/en.yml b/config/locales/en.yml index b09ab94cd..0bd238892 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -472,6 +472,7 @@ en: facebook: Facebook twitter: Twitter youtube: YouTube + whatsapp: WhatsApp spending_proposals: form: association_name_label: 'If you propose in name of an assocation or collective add the name here' diff --git a/config/locales/es.yml b/config/locales/es.yml index 7f8164335..4df6e870e 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -472,6 +472,7 @@ es: facebook: Facebook twitter: Twitter youtube: YouTube + whatsapp: WhatsApp spending_proposals: form: association_name_label: 'Si propones en nombre de una asociación o colectivo añade el nombre aquí' diff --git a/config/locales/social_share_button.en.yml b/config/locales/social_share_button.en.yml index a4ba5436f..84ee6baba 100644 --- a/config/locales/social_share_button.en.yml +++ b/config/locales/social_share_button.en.yml @@ -16,5 +16,4 @@ en: tumblr: "Tumblr" plurk: "Plurk" pinterest: "Pinterest" - email: "Email" - whatsapp: "WhatsApp" \ No newline at end of file + email: "Email" \ No newline at end of file diff --git a/config/locales/social_share_button.es.yml b/config/locales/social_share_button.es.yml index 4647fc010..aa0c3f224 100644 --- a/config/locales/social_share_button.es.yml +++ b/config/locales/social_share_button.es.yml @@ -16,5 +16,4 @@ es: tumblr: "Tumblr" plurk: "Plurk" pinterest: "Pinterest" - email: "Correo electrónico" - whatsapp: "WhatsApp" \ No newline at end of file + email: "Correo electrónico" \ No newline at end of file From 3dbdc8f455e5fe18ff25079b0745c934a5608392 Mon Sep 17 00:00:00 2001 From: kikito Date: Mon, 6 Mar 2017 19:24:10 +0100 Subject: [PATCH 458/613] Adds delete link to budget investment list in user activities --- .../budgets/investments_controller.rb | 2 +- app/views/users/_budget_investments.html.erb | 5 +++++ config/locales/en.yml | 1 + config/locales/es.yml | 1 + config/routes.rb | 2 +- spec/features/budgets/investments_spec.rb | 18 +++++++++++++++++- 6 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 0a5e78eef..7f9c6e7ee 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -55,7 +55,7 @@ module Budgets end def destroy - investment.destroy + @investment.destroy redirect_to user_path(current_user, filter: 'budget_investments'), notice: t('flash.actions.destroy.budget_investment') end diff --git a/app/views/users/_budget_investments.html.erb b/app/views/users/_budget_investments.html.erb index b5773cbdf..d16f022ce 100644 --- a/app/views/users/_budget_investments.html.erb +++ b/app/views/users/_budget_investments.html.erb @@ -4,6 +4,11 @@ <%= link_to budget_investment.title, budget_investment_path(budget_investment.budget, budget_investment) %> + + <% if can? :destroy, budget_investment %> + <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), method: :delete %> + <% end %> + <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index dd9624188..0e8462cb8 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -428,6 +428,7 @@ en: search: 'Filter' title: 'Advanced search' to: 'To' + delete: Delete author_info: author_deleted: User deleted back: Go back diff --git a/config/locales/es.yml b/config/locales/es.yml index 0b8fa4b1c..ba9b2c706 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -428,6 +428,7 @@ es: search: 'Filtrar' title: 'Búsqueda avanzada' to: 'Hasta' + delete: 'Borrar' author_info: author_deleted: Usuario eliminado back: Volver diff --git a/config/routes.rb b/config/routes.rb index cc76297f6..8d5e84ad3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -298,7 +298,7 @@ Rails.application.routes.draw do get :support_investments get :print_investments end - resources :investments, only: [:index, :new, :create, :show], controller: 'budgets/investments' do + resources :investments, only: [:index, :new, :create, :show, :destroy], controller: 'budgets/investments' do post :vote, on: :member get :print, on: :collection end diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index a6feb6f44..323948c16 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -315,6 +315,20 @@ feature 'Budget Investments' do end end + scenario "Author can destroy while on the selecting phase" do + user = create(:user, :level_two) + sp1 = create(:budget_investment, :selected, heading: heading, price: 10000, author: user) + + login_as(user) + visit user_path(user, tab: :budget_investments) + + within("#budget_investment_#{sp1.id}") do + expect(page).to have_content(sp1.title) + click_link('Delete') + end + + visit user_path(user, tab: :budget_investments) + end end context "Selecting Phase" do @@ -476,6 +490,8 @@ feature 'Budget Investments' do expect(page).to have_content "€10,000" end + + scenario "Sidebar in show should display vote text" do investment = create(:budget_investment, :selected, budget: budget) visit budget_investment_path(budget, investment) @@ -561,4 +577,4 @@ feature 'Budget Investments' do end end -end \ No newline at end of file +end From f67b8d8aeebe3806213e1390d5ca0927b7e25986 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 6 Mar 2017 19:34:47 +0100 Subject: [PATCH 459/613] improves styles of delete button --- app/views/users/_budget_investments.html.erb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/users/_budget_investments.html.erb b/app/views/users/_budget_investments.html.erb index d16f022ce..64cad676d 100644 --- a/app/views/users/_budget_investments.html.erb +++ b/app/views/users/_budget_investments.html.erb @@ -4,9 +4,10 @@ <%= link_to budget_investment.title, budget_investment_path(budget_investment.budget, budget_investment) %> - + <% if can? :destroy, budget_investment %> - <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), method: :delete %> + <%= link_to t('shared.delete'), budget_investment_path(budget_investment.budget, budget_investment), + method: :delete, class: "button hollow alert" %> <% end %> From 8f91b1e2cc064377a913aa8e6e3459439d3b61e1 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 7 Mar 2017 16:42:45 +0100 Subject: [PATCH 460/613] fixes incorrect title/setup in spec --- spec/features/budgets/investments_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 323948c16..1d812bd7e 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -315,9 +315,9 @@ feature 'Budget Investments' do end end - scenario "Author can destroy while on the selecting phase" do + scenario "Author can destroy while on the accepting phase" do user = create(:user, :level_two) - sp1 = create(:budget_investment, :selected, heading: heading, price: 10000, author: user) + sp1 = create(:budget_investment, heading: heading, price: 10000, author: user) login_as(user) visit user_path(user, tab: :budget_investments) From 712d5f2d9a6ebbc1da46099dd41770f58b3a95de Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 7 Mar 2017 18:17:49 +0100 Subject: [PATCH 461/613] displays only valuation tags for filtering --- app/helpers/budgets_helper.rb | 4 ++++ app/views/admin/budget_investments/index.html.erb | 2 +- spec/features/admin/budget_investments_spec.rb | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 84f04139c..4b9dfd311 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -38,4 +38,8 @@ module BudgetsHelper def current_ballot Budget::Ballot.where(user: current_user, budget: @budget).first end + + def investment_tags_select_options + Budget::Investment.tags_on(:valuation).order(:name).select(:name).distinct + end end diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb index 126a933b7..beb5eb856 100644 --- a/app/views/admin/budget_investments/index.html.erb +++ b/app/views/admin/budget_investments/index.html.erb @@ -28,7 +28,7 @@
    <%= select_tag :tag_name, - options_for_select(spending_proposal_tags_select_options, params[:tag_name]), + options_for_select(investment_tags_select_options, params[:tag_name]), { prompt: t("admin.budget_investments.index.tags_filter_all"), label: false, class: "js-submit-on-change" } %> diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index ede09ec4f..f4dde2425 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -252,6 +252,21 @@ feature 'Admin budget investments' do expect(page).to have_content("More schools") end + scenario "Filtering by tag, display only valuation tags" do + investment1 = create(:budget_investment, budget: @budget, tag_list: 'Education') + investment2 = create(:budget_investment, budget: @budget, tag_list: 'Health') + + investment1.set_tag_list_on(:valuation, 'Teachers') + investment2.set_tag_list_on(:valuation, 'Hospitals') + + investment1.save + investment2.save + + visit admin_budget_budget_investments_path(budget_id: @budget.id) + + expect(page).to have_select("tag_name", options: ["All tags", "Hospitals", "Teachers"]) + end + end scenario 'Show' do From dcb0e03cf4314a076618d7759ad365eca13fdaaa Mon Sep 17 00:00:00 2001 From: kikito Date: Wed, 8 Mar 2017 13:32:12 +0100 Subject: [PATCH 462/613] small i18n change --- config/locales/es.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index e674f2106..495a940a3 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -569,8 +569,8 @@ es: one: 1 Propuesta other: "%{count} Propuestas" budget_investments: - one: 1 Propuesta de inversión - other: "%{count} Propuestas de inversión" + one: 1 Proyecto de presupuestos participativos + other: "%{count} Proyectos de presupuestos participativos" no_activity: Usuario sin actividad pública no_private_messages: "Este usuario no acepta mensajes privados." private_activity: Este usuario ha decidido mantener en privado su lista de actividades From 9e582245d367f1cafdb1b0e0498fac2742b892a8 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 10 Mar 2017 12:04:47 +0100 Subject: [PATCH 463/613] avoids use tabindex attribute --- app/views/devise/sessions/new.html.erb | 10 ++++------ app/views/users/registrations/new.html.erb | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index ad375e772..910135853 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -11,18 +11,18 @@ <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
    - <%= f.email_field :email, autofocus: true, placeholder: t("devise_views.sessions.new.email_label"), tabindex: "1" %> + <%= f.email_field :email, autofocus: true, placeholder: t("devise_views.sessions.new.email_label") %>
    - <%= link_to t("devise_views.shared.links.new_password"), new_password_path(resource_name), class: "float-right", tabindex: "3" %> - <%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.sessions.new.password_label"), tabindex: "2" %> + <%= f.password_field :password, autocomplete: "off", placeholder: t("devise_views.sessions.new.password_label") %> + <%= link_to t("devise_views.shared.links.new_password"), new_password_path(resource_name), class: "float-right" %>
    <% if devise_mapping.rememberable? -%>
    <%= f.label :remember_me do %> - <%= f.check_box :remember_me, title: t('devise_views.sessions.new.remember_me'), label: false, tabindex: "4" %> + <%= f.check_box :remember_me, title: t('devise_views.sessions.new.remember_me'), label: false %> <%= t("devise_views.sessions.new.remember_me") %> <% end %>
    @@ -35,5 +35,3 @@ <% end %> <%= render "devise/shared/links" %> - - diff --git a/app/views/users/registrations/new.html.erb b/app/views/users/registrations/new.html.erb index 1c6f81455..3ae3156f7 100644 --- a/app/views/users/registrations/new.html.erb +++ b/app/views/users/registrations/new.html.erb @@ -19,7 +19,7 @@ <%= f.label :username %>

    <%= t("devise_views.users.registrations.new.username_note") %>

    - <%= f.text_field :username, maxlength: User.username_max_length, placeholder: t("devise_views.users.registrations.new.username_label"), label: false %> + <%= f.text_field :username, autofocus: true, maxlength: User.username_max_length, placeholder: t("devise_views.users.registrations.new.username_label"), label: false %> <%= f.invisible_captcha :family_name %> From a7b9f830164b4e1e12b6fb8a33a15665ba81af9d Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 10 Mar 2017 12:06:33 +0100 Subject: [PATCH 464/613] fixes contrast color on form social buttons --- app/assets/stylesheets/layout.scss | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 1511910b1..baa6853d2 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1167,6 +1167,9 @@ table { .button.button-twitter, .button.button-facebook, .button.button-google { + background: white; + color: $text; + font-weight: bold; height: $line-height*2; line-height: $line-height*2; padding: 0; @@ -1174,9 +1177,11 @@ table { } .button.button-twitter { - background: #45B0E3; + background: #ECF7FC; + border-left: 3px solid #45B0E3; &:before { + color: #45B0E3; content: "f"; font-family: "icons" !important; font-size: rem-calc(24); @@ -1214,9 +1219,11 @@ table { } .button.button-facebook { - background: #3B5998; + background: #EBEEF4; + border-left: 3px solid #3B5998; &:before { + color: #3B5998; content: "A"; font-family: "icons" !important; font-size: rem-calc(24); @@ -1254,9 +1261,11 @@ table { } .button.button-google { - background: #DE4C34; + background: #FCEDEA; + border-left: 3px solid #DE4C34; &:before { + color: #DE4C34; content: "B"; font-family: "icons" !important; font-size: rem-calc(24); From f3da84bc20c9602441ac395d1b6446d418e10aff Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 10 Mar 2017 12:55:56 +0100 Subject: [PATCH 465/613] improves colors contrast --- app/assets/stylesheets/layout.scss | 5 +++-- app/assets/stylesheets/participation.scss | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 1511910b1..e6d7dc5a2 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1104,11 +1104,12 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar { // -------------------- [class^="level-"] { - color: white; + color: black; } .is-author { - background: #008CCF; + background: #00A5F1; + color: black; } .is-association { diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index c72b981c7..235b58291 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -455,7 +455,7 @@ } .bullet { - color: $border; + color: $text; } .investment-project-show p, .budget-investment-show p { From 11e5dee9a3bf639150d18fef50f37452561a1ca3 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 10 Mar 2017 12:57:40 +0100 Subject: [PATCH 466/613] removes placeholder on input date --- app/views/shared/_advanced_search.html.erb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/shared/_advanced_search.html.erb b/app/views/shared/_advanced_search.html.erb index 7ce6108b4..56157c4a7 100644 --- a/app/views/shared/_advanced_search.html.erb +++ b/app/views/shared/_advanced_search.html.erb @@ -37,7 +37,6 @@ <%= text_field_tag 'advanced_search[date_min]', params[:advanced_search].try(:[], :date_min), type: "date", - placeholder: t("shared.advanced_search.date_placeholder"), class: 'js-calendar' %>
    @@ -47,7 +46,6 @@ <%= text_field_tag 'advanced_search[date_max]', params[:advanced_search].try(:[], :date_max), type: "date", - placeholder: t("shared.advanced_search.date_placeholder"), class: 'js-calendar' %>
    From c6617e5c4af9092676880d47075be403ec7ee04c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 13 Mar 2017 11:57:58 +0100 Subject: [PATCH 467/613] updates minor gem versions --- Gemfile | 38 +++++++-------- Gemfile.lock | 128 +++++++++++++++++++++++++++------------------------ 2 files changed, 86 insertions(+), 80 deletions(-) diff --git a/Gemfile b/Gemfile index 13a0b3567..81b87806d 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'pg', '~> 0.19.0' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0', '>= 5.0.4' # Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '>= 3.0.4' +gem 'uglifier', '~> 3.1.6' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2.1' # See https://github.com/rails/execjs#readme for more supported runtimes @@ -40,11 +40,11 @@ gem 'foundation_rails_helper', '~> 2.0.0' gem 'acts_as_votable' gem 'ckeditor', '~> 4.2.2' gem 'invisible_captcha', '~> 0.9.2' -gem 'cancancan' +gem 'cancancan', '~> 1.16.0' gem 'social-share-button' gem 'initialjs-rails', '0.2.0.4' gem 'unicorn', '~> 5.2.0' -gem 'paranoia', '~> 2.2.0' +gem 'paranoia', '~> 2.2.1' gem 'rinku', '~> 2.0.2', require: 'rails_rinku' gem 'savon' gem 'dalli' @@ -52,18 +52,18 @@ gem 'rollbar', '~> 2.14.0' gem 'delayed_job_active_record', '~> 4.1.0' gem 'daemons' gem 'devise-async' -gem 'newrelic_rpm', '~> 3.17.2.327' +gem 'newrelic_rpm', '~> 3.18.1.330' gem 'whenever', require: false gem 'pg_search' -gem 'sitemap_generator' +gem 'sitemap_generator', '~> 5.3.1' gem 'ahoy_matey', '~> 1.5.3' -gem 'groupdate', '~> 3.1.0' # group temporary data +gem 'groupdate', '~> 3.2.0' # group temporary data gem 'tolk', '~> 2.0.0' # Web interface for translations gem 'browser' gem 'turnout', '~> 2.4.0' -gem 'redcarpet' +gem 'redcarpet', '~> 3.4.0' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console @@ -72,28 +72,28 @@ group :development, :test do gem 'spring' gem 'spring-commands-rspec' gem 'rspec-rails', '~> 3.5' - gem 'capybara' - gem 'factory_girl_rails' + gem 'capybara', '~> 2.12.1' + gem 'factory_girl_rails', '~> 4.8.0' gem 'fuubar' gem 'launchy' gem 'quiet_assets' - gem 'letter_opener_web', '~> 1.3.0' - gem 'i18n-tasks' - gem 'capistrano', '3.5.0', require: false + gem 'letter_opener_web', '~> 1.3.1' + gem 'i18n-tasks', '~> 0.9.12' + gem 'capistrano', '~> 3.7.2', require: false gem 'capistrano-bundler', '~> 1.2', require: false - gem "capistrano-rails", '1.1.8', require: false + gem "capistrano-rails", '~> 1.2.3', require: false gem 'rvm1-capistrano3', require: false - gem 'capistrano3-delayed-job', '~> 1.0' - gem "bullet" - gem "faker" - gem 'rubocop', '~> 0.45.0', require: false + gem 'capistrano3-delayed-job', '~> 1.7.3' + gem "bullet", '~> 5.5.1' + gem "faker", '~> 1.7.3' + gem 'rubocop', '~> 0.47.1', require: false gem 'knapsack' end group :test do gem 'database_cleaner' - gem 'poltergeist' - gem 'coveralls', require: false + gem 'poltergeist', '~> 1.13.0' + gem 'coveralls', '~> 0.8.19', require: false gem 'email_spec' end diff --git a/Gemfile.lock b/Gemfile.lock index e2c21605c..f8e67edab 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,8 +39,9 @@ GEM acts-as-taggable-on (3.5.0) activerecord (>= 3.2, < 5) acts_as_votable (0.10.0) - addressable (2.4.0) - ahoy_matey (1.5.3) + addressable (2.5.0) + public_suffix (~> 2.0, >= 2.0.2) + ahoy_matey (1.5.4) addressable browser (~> 2.0) geocoder @@ -51,14 +52,14 @@ GEM safely_block (>= 0.1.1) user_agent_parser uuidtools - airbrussh (1.1.1) + airbrussh (1.1.2) sshkit (>= 1.6.1, != 1.7.0) akami (1.3.1) gyoku (>= 0.4.0) nokogiri ancestry (2.2.2) activerecord (>= 3.0.0) - arel (6.0.3) + arel (6.0.4) ast (2.3.0) babel-source (5.8.35) babel-transpiler (0.7.0) @@ -66,13 +67,13 @@ GEM execjs (~> 2.0) bcrypt (3.1.11) browser (2.3.0) - builder (3.2.2) - bullet (5.4.2) + builder (3.2.3) + bullet (5.5.1) activesupport (>= 3.0.0) uniform_notifier (~> 1.10.0) byebug (9.0.6) - cancancan (1.15.0) - capistrano (3.5.0) + cancancan (1.16.0) + capistrano (3.7.2) airbrussh (>= 1.0.0) capistrano-harrow i18n @@ -82,12 +83,13 @@ GEM capistrano (~> 3.1) sshkit (~> 1.2) capistrano-harrow (0.5.3) - capistrano-rails (1.1.8) + capistrano-rails (1.2.3) capistrano (~> 3.1) capistrano-bundler (~> 1.1) - capistrano3-delayed-job (1.7.2) + capistrano3-delayed-job (1.7.3) capistrano (~> 3.0, >= 3.0.0) - capybara (2.7.1) + daemons (~> 1.2.4) + capybara (2.12.1) addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -111,7 +113,7 @@ GEM execjs coffee-script-source (1.10.0) concurrent-ruby (1.0.4) - coveralls (0.8.17) + coveralls (0.8.19) json (>= 1.8, < 3) simplecov (~> 0.12.0) term-ansicolor (~> 1.3) @@ -151,12 +153,12 @@ GEM errbase (0.0.3) erubis (2.7.0) execjs (2.7.0) - factory_girl (4.7.0) + factory_girl (4.8.0) activesupport (>= 3.0.0) - factory_girl_rails (4.7.0) - factory_girl (~> 4.7.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) railties (>= 3.0.0) - faker (1.6.6) + faker (1.7.3) i18n (~> 0.5) faraday (0.9.2) multipart-post (>= 1.2, < 3) @@ -173,10 +175,10 @@ GEM fuubar (2.2.0) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) - geocoder (1.4.1) + geocoder (1.4.3) globalid (0.3.7) activesupport (>= 4.1.0) - groupdate (3.1.1) + groupdate (3.2.0) activesupport (>= 3) gyoku (1.3.1) builder (>= 2.1.2) @@ -185,8 +187,8 @@ GEM htmlentities (4.3.4) httpi (2.4.1) rack - i18n (0.7.0) - i18n-tasks (0.9.6) + i18n (0.8.1) + i18n-tasks (0.9.12) activesupport (>= 4.0.2) ast (>= 2.1.0) easy_translate (>= 0.5.0) @@ -219,7 +221,7 @@ GEM addressable (~> 2.3) letter_opener (1.4.1) launchy (~> 2.2) - letter_opener_web (1.3.0) + letter_opener_web (1.3.1) actionmailer (>= 3.2) letter_opener (~> 1.0) railties (>= 3.2) @@ -237,9 +239,9 @@ GEM multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (3.2.0) - newrelic_rpm (3.17.2.327) - nokogiri (1.6.8.1) + net-ssh (4.1.0) + newrelic_rpm (3.18.1.330) + nokogiri (1.7.0.1) mini_portile2 (~> 2.1.0) nori (2.6.0) oauth (0.5.0) @@ -269,20 +271,21 @@ GEM json (~> 1.3) omniauth-oauth (~> 1.1) orm_adapter (0.5.0) - paranoia (2.2.0) + paranoia (2.2.1) activerecord (>= 4.0, < 5.1) - parser (2.3.3.1) + parser (2.4.0.0) ast (~> 2.2) pg (0.19.0) pg_search (1.0.6) activerecord (>= 3.1) activesupport (>= 3.1) arel - poltergeist (1.10.0) + poltergeist (1.13.0) capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) powerpack (0.1.1) + public_suffix (2.0.5) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) rack (1.6.5) @@ -305,9 +308,9 @@ GEM sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) - rails-dom-testing (1.0.7) + rails-dom-testing (1.0.8) activesupport (>= 4.2.0.beta, < 5.0) - nokogiri (~> 1.6.0) + nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) @@ -316,12 +319,12 @@ GEM activesupport (= 4.2.7.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.1.0) + rainbow (2.2.1) raindrops (0.17.0) rake (12.0.0) - redcarpet (3.3.4) + redcarpet (3.4.0) referer-parser (0.3.0) - request_store (1.3.1) + request_store (1.3.2) responders (2.3.0) railties (>= 4.2.0, < 5.1) rinku (2.0.2) @@ -344,8 +347,8 @@ GEM rspec-mocks (~> 3.5.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) - rubocop (0.45.0) - parser (>= 2.3.1.1, < 3.0) + rubocop (0.47.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) @@ -355,7 +358,7 @@ GEM capistrano (~> 3.0) sshkit (>= 1.2) safe_yaml (1.0.4) - safely_block (0.1.1) + safely_block (0.2.0) errbase sass (3.4.22) sass-rails (5.0.6) @@ -377,7 +380,7 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.0) - sitemap_generator (5.2.0) + sitemap_generator (5.3.1) builder (~> 3.0) social-share-button (0.3.1) coffee-rails @@ -396,7 +399,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sshkit (1.11.4) + sshkit (1.12.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) term-ansicolor (1.4.0) @@ -405,10 +408,10 @@ GEM unicode-display_width (~> 1.1.1) thor (0.19.4) thread (0.2.2) - thread_safe (0.3.5) + thread_safe (0.3.6) tilt (2.0.5) timecop (0.8.1) - tins (1.13.0) + tins (1.13.2) tolk (2.0.0) rails (>= 4.0) safe_yaml (>= 0.8.6) @@ -421,9 +424,9 @@ GEM tilt (>= 1.4, < 3) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (3.0.4) + uglifier (3.1.6) execjs (>= 0.3.0, < 3) - unicode-display_width (1.1.1) + unicode-display_width (1.1.3) unicorn (5.2.0) kgio (~> 2.6) raindrops (~> 0.7) @@ -439,7 +442,7 @@ GEM activemodel (>= 4.2) debug_inspector railties (>= 4.2) - websocket-driver (0.6.4) + websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) whenever (0.9.7) @@ -456,17 +459,17 @@ DEPENDENCIES ahoy_matey (~> 1.5.3) ancestry (~> 2.2.2) browser - bullet + bullet (~> 5.5.1) byebug - cancancan - capistrano (= 3.5.0) + cancancan (~> 1.16.0) + capistrano (~> 3.7.2) capistrano-bundler (~> 1.2) - capistrano-rails (= 1.1.8) - capistrano3-delayed-job (~> 1.0) - capybara + capistrano-rails (~> 1.2.3) + capistrano3-delayed-job (~> 1.7.3) + capybara (~> 2.12.1) ckeditor (~> 4.2.2) coffee-rails (~> 4.2.1) - coveralls + coveralls (~> 0.8.19) daemons dalli database_cleaner @@ -475,13 +478,13 @@ DEPENDENCIES devise-async devise_security_extension email_spec - factory_girl_rails - faker + factory_girl_rails (~> 4.8.0) + faker (~> 1.7.3) foundation-rails (~> 6.2.4.0) foundation_rails_helper (~> 2.0.0) fuubar - groupdate (~> 3.1.0) - i18n-tasks + groupdate (~> 3.2.0) + i18n-tasks (~> 0.9.12) initialjs-rails (= 0.2.0.4) invisible_captcha (~> 0.9.2) jquery-rails (~> 4.2.2) @@ -489,28 +492,28 @@ DEPENDENCIES kaminari knapsack launchy - letter_opener_web (~> 1.3.0) - newrelic_rpm (~> 3.17.2.327) + letter_opener_web (~> 1.3.1) + newrelic_rpm (~> 3.18.1.330) omniauth omniauth-facebook (~> 3.0.0) omniauth-google-oauth2 (~> 0.4.0) omniauth-twitter - paranoia (~> 2.2.0) + paranoia (~> 2.2.1) pg (~> 0.19.0) pg_search - poltergeist + poltergeist (~> 1.13.0) quiet_assets rails (= 4.2.7.1) - redcarpet + redcarpet (~> 3.4.0) responders (~> 2.3.0) rinku (~> 2.0.2) rollbar (~> 2.14.0) rspec-rails (~> 3.5) - rubocop (~> 0.45.0) + rubocop (~> 0.47.1) rvm1-capistrano3 sass-rails (~> 5.0, >= 5.0.4) savon - sitemap_generator + sitemap_generator (~> 5.3.1) social-share-button spring spring-commands-rspec @@ -518,7 +521,10 @@ DEPENDENCIES tolk (~> 2.0.0) turbolinks turnout (~> 2.4.0) - uglifier (>= 3.0.4) + uglifier (~> 3.1.6) unicorn (~> 5.2.0) web-console (= 3.3.0) whenever + +BUNDLED WITH + 1.13.7 From d0ada346319193b4a55e5bf211d058be0e82aec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 14 Mar 2017 12:01:46 +0100 Subject: [PATCH 468/613] rails version up to 4.2.8 --- Gemfile | 2 +- Gemfile.lock | 65 ++++++++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/Gemfile b/Gemfile index 81b87806d..262a44ba4 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '4.2.7.1' +gem 'rails', '4.2.8' # Use PostgreSQL gem 'pg', '~> 0.19.0' # Use SCSS for stylesheets diff --git a/Gemfile.lock b/Gemfile.lock index f8e67edab..738087adf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,38 +1,37 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) + actionmailer (4.2.8) + actionpack (= 4.2.8) + actionview (= 4.2.8) + activejob (= 4.2.8) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.7.1) - actionview (= 4.2.7.1) - activesupport (= 4.2.7.1) + actionpack (4.2.8) + actionview (= 4.2.8) + activesupport (= 4.2.8) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.7.1) - activesupport (= 4.2.7.1) + actionview (4.2.8) + activesupport (= 4.2.8) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - activejob (4.2.7.1) - activesupport (= 4.2.7.1) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (4.2.8) + activesupport (= 4.2.8) globalid (>= 0.3.0) - activemodel (4.2.7.1) - activesupport (= 4.2.7.1) + activemodel (4.2.8) + activesupport (= 4.2.8) builder (~> 3.1) - activerecord (4.2.7.1) - activemodel (= 4.2.7.1) - activesupport (= 4.2.7.1) + activerecord (4.2.8) + activemodel (= 4.2.8) + activesupport (= 4.2.8) arel (~> 6.0) - activesupport (4.2.7.1) + activesupport (4.2.8) i18n (~> 0.7) - json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) @@ -208,7 +207,7 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.5) railties (>= 3.2.16) - json (1.8.3) + json (1.8.6) jwt (1.5.4) kaminari (0.17.0) actionpack (>= 3.0.0) @@ -295,16 +294,16 @@ GEM rack rack-test (0.6.3) rack (>= 1.0) - rails (4.2.7.1) - actionmailer (= 4.2.7.1) - actionpack (= 4.2.7.1) - actionview (= 4.2.7.1) - activejob (= 4.2.7.1) - activemodel (= 4.2.7.1) - activerecord (= 4.2.7.1) - activesupport (= 4.2.7.1) + rails (4.2.8) + actionmailer (= 4.2.8) + actionpack (= 4.2.8) + actionview (= 4.2.8) + activejob (= 4.2.8) + activemodel (= 4.2.8) + activerecord (= 4.2.8) + activesupport (= 4.2.8) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.7.1) + railties (= 4.2.8) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -314,9 +313,9 @@ GEM rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (4.2.7.1) - actionpack (= 4.2.7.1) - activesupport (= 4.2.7.1) + railties (4.2.8) + actionpack (= 4.2.8) + activesupport (= 4.2.8) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.2.1) @@ -503,7 +502,7 @@ DEPENDENCIES pg_search poltergeist (~> 1.13.0) quiet_assets - rails (= 4.2.7.1) + rails (= 4.2.8) redcarpet (~> 3.4.0) responders (~> 2.3.0) rinku (~> 2.0.2) From ed44d8cc5f76fc00c3f10ae13b55fcf25d80b3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 14 Mar 2017 12:03:14 +0100 Subject: [PATCH 469/613] removes wrong search attribute --- app/views/shared/_tags.html.erb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/shared/_tags.html.erb b/app/views/shared/_tags.html.erb index 3cdb3c40e..ec2b7a1b1 100644 --- a/app/views/shared/_tags.html.erb +++ b/app/views/shared/_tags.html.erb @@ -5,8 +5,7 @@ <% taggable.tag_list_with_limit(limit).each do |tag| %>
  • <%= link_to sanitize(tag.name), - taggables_path(taggable.class.name.underscore, tag.name), - search: tag.name %>
  • + taggables_path(taggable.class.name.underscore, tag.name) %> <% end %> <% if taggable.tags_count_out_of_limit(limit) > 0 %> From 2d3e3586d1531418ab2aceed988b43f65176c05b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 14 Mar 2017 13:30:31 +0100 Subject: [PATCH 470/613] updates capistrano scm config --- Capfile | 4 ++++ config/deploy.rb | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Capfile b/Capfile index 1a33b63f0..ea11eb9b6 100644 --- a/Capfile +++ b/Capfile @@ -12,6 +12,10 @@ require 'capistrano/delayed_job' require 'whenever/capistrano' require 'rvm1/capistrano3' +#SCM: Git +require "capistrano/scm/git" +install_plugin Capistrano::SCM::Git + # Load custom tasks from `lib/capistrano/tasks` if you have any defined Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r } diff --git a/config/deploy.rb b/config/deploy.rb index 52fa7a255..5b842cef6 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -15,7 +15,6 @@ set :full_app_name, deploysecret(:full_app_name) set :server_name, deploysecret(:server_name) set :repo_url, 'https://github.com/consul/consul.git' -set :scm, :git set :revision, `git rev-parse --short #{fetch(:branch)}`.strip set :log_level, :info From 45def094fe45a078b6db4e29880f1d107a49beb0 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 14 Mar 2017 18:42:21 +0100 Subject: [PATCH 471/613] removes accesskey on top links and login items links --- app/views/devise/menu/_login_items.html.erb | 12 ++++++------ app/views/shared/_top_links.html.erb | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/views/devise/menu/_login_items.html.erb b/app/views/devise/menu/_login_items.html.erb index 0ab28e2ee..b7db4a22c 100644 --- a/app/views/devise/menu/_login_items.html.erb +++ b/app/views/devise/menu/_login_items.html.erb @@ -1,6 +1,6 @@ <% if user_signed_in? %>
  • - <%= link_to notifications_path, class: "notifications", accesskey: "n" do %> + <%= link_to notifications_path, class: "notifications" do %> <%= t("layouts.header.notifications") %> <% if current_user.notifications_count > 0 %> @@ -12,19 +12,19 @@ <% end %>
  • - <%= link_to(t("layouts.header.my_activity_link"), user_path(current_user), accesskey: "a") %> + <%= link_to t("layouts.header.my_activity_link"), user_path(current_user) %>
  • - <%= link_to(t("layouts.header.my_account_link"), account_path, accesskey: "m") %> + <%= link_to t("layouts.header.my_account_link"), account_path %>
  • - <%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %> + <%= link_to t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete %>
  • <% else %>
  • - <%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %> + <%= link_to t("devise_views.menu.login_items.login"), new_user_session_path %>
  • - <%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button") %> + <%= link_to t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button" %>
  • <% end %> diff --git a/app/views/shared/_top_links.html.erb b/app/views/shared/_top_links.html.erb index b6b738aca..40cda54de 100644 --- a/app/views/shared/_top_links.html.erb +++ b/app/views/shared/_top_links.html.erb @@ -2,8 +2,7 @@
  • <%= link_to t("layouts.header.more_information"), page_path('more_information'), - class: ("selected" if current_page?("/more_information")), - accesskey: "i" %> + class: ("selected" if current_page?("/more_information")) %>
  • <%= link_to t("layouts.header.external_link_transparency"), From 02cb83c6835aaf3cd4303884edb528d3fc4b28e1 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 14 Mar 2017 18:43:02 +0100 Subject: [PATCH 472/613] changes accesskey letters to numbers --- app/views/layouts/_header.html.erb | 2 +- app/views/pages/accessibility.html.erb | 28 +++++++----------------- app/views/shared/_subnavigation.html.erb | 11 +++++----- 3 files changed, 14 insertions(+), 27 deletions(-) diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 223f173b2..9a33662c6 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -21,7 +21,7 @@
    - <%= link_to root_path, class: "hide-for-small-only", accesskey: "/" do %> + <%= link_to root_path, class: "hide-for-small-only", accesskey: "0" do %> <%= image_tag('logo_header.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> <%= setting['org_name'] %> <% end %> diff --git a/app/views/pages/accessibility.html.erb b/app/views/pages/accessibility.html.erb index a2c2eff30..197885370 100644 --- a/app/views/pages/accessibility.html.erb +++ b/app/views/pages/accessibility.html.erb @@ -27,37 +27,25 @@ - / + 0 Inicio - D + 1 Debates - P + 2 Propuestas - S + 3 + Votaciones + + + 4 Presupuestos participativos - - I - Más información - - - N - Notificaciones - - - A - Mi actividad - - - M - Mi cuenta -
    diff --git a/app/views/shared/_subnavigation.html.erb b/app/views/shared/_subnavigation.html.erb index ed5694f27..f7bc3c810 100644 --- a/app/views/shared/_subnavigation.html.erb +++ b/app/views/shared/_subnavigation.html.erb @@ -5,27 +5,26 @@ <%= layout_menu_link_to t("layouts.header.debates"), debates_path, controller_name == 'debates', - accesskey: "d" %> + accesskey: "1" %>
  • <% end %>
  • <%= layout_menu_link_to t("layouts.header.proposals"), proposals_path, controller_name == 'proposals', - accesskey: "p" %> + accesskey: "2" %>
  • <%= layout_menu_link_to t("layouts.header.proposal_ballot"), proposal_ballots_path, controller_name == 'proposal_ballots', - accesskey: "v" %> + accesskey: "3" %>
  • <% if feature?(:spending_proposals) %>
  • <%= layout_menu_link_to t("layouts.header.spending_proposals"), spending_proposals_path, - controller_name == 'spending_proposals', - accesskey: "s" %> + controller_name == 'spending_proposals' %>
  • <% end %> <% if feature?(:budgets) %> @@ -33,7 +32,7 @@ <%= layout_menu_link_to t("layouts.header.budgets"), budgets_path, controller_name == "budgets" || controller_name == "investments", - accesskey: "b" %> + accesskey: "4" %> <% end %> From 7541956f5b68e6671289944480b54e14d540cf8d Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 14 Mar 2017 18:45:35 +0100 Subject: [PATCH 473/613] adds captions to accessibility page tables --- app/views/pages/accessibility.html.erb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/pages/accessibility.html.erb b/app/views/pages/accessibility.html.erb index 197885370..de5e64277 100644 --- a/app/views/pages/accessibility.html.erb +++ b/app/views/pages/accessibility.html.erb @@ -19,6 +19,7 @@
    + @@ -54,6 +55,7 @@
    Atajos de teclado para el menú de navegación
    Tecla
    + From e9bc450745aabbda07b1b2adb99890ec761d4348 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 14 Mar 2017 19:11:00 +0100 Subject: [PATCH 474/613] adds scope attribute on accessibility page tables --- app/views/pages/accessibility.html.erb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/pages/accessibility.html.erb b/app/views/pages/accessibility.html.erb index de5e64277..a0f54760d 100644 --- a/app/views/pages/accessibility.html.erb +++ b/app/views/pages/accessibility.html.erb @@ -22,8 +22,8 @@ - - + + @@ -58,8 +58,8 @@ - - + + @@ -94,8 +94,8 @@
    Combinación de teclas dependiendo del sistema operativo y navegador
    Navegador
    Atajos de teclado para el menú de navegación
    TeclaPáginaTeclaPágina
    Combinación de teclas dependiendo del sistema operativo y navegador
    NavegadorCombinación de teclasNavegadorCombinación de teclas
    - - + + From ea63c1ccf061922356adae7bad47479a1dc3946b Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 14 Mar 2017 19:19:38 +0100 Subject: [PATCH 475/613] adds accesskey to outdated spending proprosals menu --- app/views/shared/_subnavigation.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/shared/_subnavigation.html.erb b/app/views/shared/_subnavigation.html.erb index f7bc3c810..32dc73aa7 100644 --- a/app/views/shared/_subnavigation.html.erb +++ b/app/views/shared/_subnavigation.html.erb @@ -24,7 +24,8 @@
  • <%= layout_menu_link_to t("layouts.header.spending_proposals"), spending_proposals_path, - controller_name == 'spending_proposals' %> + controller_name == 'spending_proposals', + accesskey: "s" %>
  • <% end %> <% if feature?(:budgets) %> From 170cb89a5c1ca90af42aa2ffabf3f8bfa62fa979 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 15 Mar 2017 14:50:50 +0100 Subject: [PATCH 476/613] allows admins to see budgets in reviewing and selecting phase --- .../management/budgets_controller.rb | 9 +++ .../management/budget_investments_spec.rb | 55 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/app/controllers/management/budgets_controller.rb b/app/controllers/management/budgets_controller.rb index c5cfdee76..dd7259c99 100644 --- a/app/controllers/management/budgets_controller.rb +++ b/app/controllers/management/budgets_controller.rb @@ -7,6 +7,11 @@ class Management::BudgetsController < Management::BaseController def create_investments @budgets = Budget.accepting.order(created_at: :desc).page(params[:page]) + + if current_manager_administrator? + @budgets += Budget.reviewing.order(created_at: :desc) + + Budget.selecting.order(created_at: :desc) + end end def support_investments @@ -23,4 +28,8 @@ class Management::BudgetsController < Management::BaseController check_verified_user t("management.budget_investments.alert.unverified_user") end + def current_manager_administrator? + session[:manager]["login"].match("admin") + end + end diff --git a/spec/features/management/budget_investments_spec.rb b/spec/features/management/budget_investments_spec.rb index 5b3961306..c4d7a8797 100644 --- a/spec/features/management/budget_investments_spec.rb +++ b/spec/features/management/budget_investments_spec.rb @@ -137,6 +137,61 @@ feature 'Budget Investments' do end end + scenario "Listing - managers can see budgets in accepting phase" do + accepting_budget = create(:budget, phase: "accepting") + reviewing_budget = create(:budget, phase: "reviewing") + selecting_budget = create(:budget, phase: "selecting") + valuating_budget = create(:budget, phase: "valuating") + balloting_budget = create(:budget, phase: "balloting") + reviewing_ballots_budget = create(:budget, phase: "reviewing_ballots") + finished = create(:budget, phase: "finished") + + user = create(:user, :level_two) + login_managed_user(user) + + click_link "Create budget investment" + + expect(page).to have_content(accepting_budget.name) + + expect(page).to_not have_content(reviewing_budget.name) + expect(page).to_not have_content(selecting_budget.name) + expect(page).to_not have_content(valuating_budget.name) + expect(page).to_not have_content(balloting_budget.name) + expect(page).to_not have_content(reviewing_ballots_budget.name) + expect(page).to_not have_content(finished.name) + end + + scenario "Listing - admins can see budgets in accepting, reviewing and selecting phases" do + accepting_budget = create(:budget, phase: "accepting") + reviewing_budget = create(:budget, phase: "reviewing") + selecting_budget = create(:budget, phase: "selecting") + valuating_budget = create(:budget, phase: "valuating") + balloting_budget = create(:budget, phase: "balloting") + reviewing_ballots_budget = create(:budget, phase: "reviewing_ballots") + finished = create(:budget, phase: "finished") + + visit root_path + click_link "Sign out" + + admin = create(:administrator) + login_as(admin.user) + + user = create(:user, :level_two) + login_managed_user(user) + visit management_sign_in_path + + click_link "Create budget investment" + + expect(page).to have_content(accepting_budget.name) + expect(page).to have_content(reviewing_budget.name) + expect(page).to have_content(selecting_budget.name) + + expect(page).to_not have_content(valuating_budget.name) + expect(page).to_not have_content(balloting_budget.name) + expect(page).to_not have_content(reviewing_ballots_budget.name) + expect(page).to_not have_content(finished.name) + end + context "Supporting" do scenario 'Supporting budget investments on behalf of someone in index view', :js do From 85c5e584fb19f3d66312bc72c9e71a15b4267459 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 15 Mar 2017 18:49:17 +0100 Subject: [PATCH 477/613] adds comprehensive specs for permissions to vote an investment --- spec/models/budget/investment_spec.rb | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index abbc8ad26..3725b91f3 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -285,6 +285,45 @@ describe Budget::Investment do expect(salamanca_investment.valid_heading?(user)).to eq(false) end + + it "allows votes in a group with a single heading" do + all_city_investment = create(:budget_investment, heading: heading) + expect(all_city_investment.valid_heading?(user)).to eq(true) + end + + it "allows votes in a group with a single heading after voting in that heading" do + all_city_investment1 = create(:budget_investment, heading: heading) + all_city_investment2 = create(:budget_investment, heading: heading) + + create(:vote, votable: all_city_investment1, voter: user) + + expect(all_city_investment2.valid_heading?(user)).to eq(true) + end + + it "allows votes in a group with a single heading after voting in another group" do + districts = create(:budget_group, budget: budget) + carabanchel = create(:budget_heading, group: districts) + + all_city_investment = create(:budget_investment, heading: heading) + carabanchel_investment = create(:budget_investment, heading: carabanchel) + + create(:vote, votable: carabanchel_investment, voter: user) + + expect(all_city_investment.valid_heading?(user)).to eq(true) + end + + it "allows votes in a group with multiple headings after voting in group with a single heading" do + districts = create(:budget_group, budget: budget) + carabanchel = create(:budget_heading, group: districts) + salamanca = create(:budget_heading, group: districts) + + all_city_investment = create(:budget_investment, heading: heading) + carabanchel_investment = create(:budget_investment, heading: carabanchel) + + create(:vote, votable: all_city_investment, voter: user) + + expect(carabanchel_investment.valid_heading?(user)).to eq(true) + end end end From b8b7cda4e6ed399c8b3997172c437bd77c653bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 16 Mar 2017 14:30:31 +0100 Subject: [PATCH 478/613] keeps Budget::Investment's group in sync with heading --- app/models/budget/investment.rb | 2 +- spec/models/budget/investment_spec.rb | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 100433707..230e25d82 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -259,7 +259,7 @@ class Budget private def set_denormalized_ids - self.group_id ||= self.heading.try(:group_id) + self.group_id = self.heading.try(:group_id) if self.heading_id_changed? self.budget_id ||= self.heading.try(:group).try(:budget_id) end end diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index abbc8ad26..e36a1c062 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -35,6 +35,25 @@ describe Budget::Investment do expect(investment.description).to eq("alert('danger');") end + it "set correct group and budget ids" do + budget = create(:budget) + group_1 = create(:budget_group, budget: budget) + group_2 = create(:budget_group, budget: budget) + + heading_1 = create(:budget_heading, group: group_1) + heading_2 = create(:budget_heading, group: group_2) + + investment = create(:budget_investment, heading: heading_1) + + expect(investment.budget_id).to eq budget.id + expect(investment.group_id).to eq group_1.id + + investment.update(heading: heading_2) + + expect(investment.budget_id).to eq budget.id + expect(investment.group_id).to eq group_2.id + end + describe "#unfeasibility_explanation" do it "should be valid if valuation not finished" do investment.unfeasibility_explanation = "" From 8f13c0e2ec7e49f43f40dba5c526602d49b867fa Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 16 Mar 2017 17:04:36 +0100 Subject: [PATCH 479/613] adds setting to add per page code on and --- app/views/layouts/application.html.erb | 4 +++- config/locales/fr.yml | 3 ++- config/locales/pt-BR.yml | 3 ++- config/locales/settings.en.yml | 3 ++- config/locales/settings.es.yml | 3 ++- db/dev_seeds.rb | 3 ++- db/seeds.rb | 7 +++++-- 7 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 7a1dae4d9..ef4455320 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -20,9 +20,11 @@ type: "image/png" %> <%= content_for :social_media_meta_tags %> - <%= setting['per_page_code'].try(:html_safe) %> + <%= setting['per_page_code_head'].try(:html_safe) %> + <%= setting['per_page_code_body'].try(:html_safe) %> +

    <%= setting['org_name'] %>

    diff --git a/config/locales/fr.yml b/config/locales/fr.yml index cc0b1c590..25ed4b86e 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1354,7 +1354,8 @@ fr: official_level_3_name: Niveau 3 personne officielle official_level_4_name: Niveau 4 personne officielle official_level_5_name: Niveau 5 personne officielle - per_page_code: Code à inclure dans chaque page + per_page_code_head: "Code à inclure dans chaque page ()" + per_page_code_body: "Code à inclure dans chaque page ()" proposal_code_prefix: Préfixe pour les codes de propositions votes_for_proposal_success: Nombre de votes nécessaires pour l'approbation d'une proposition diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index febe0ed5c..4718085a4 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1370,7 +1370,8 @@ pt-BR: official_level_3_name: Nível 3 coordenador público official_level_4_name: Nível 4 coordenador público official_level_5_name: Nível 5 coordenador público - per_page_code: Código a ser incluído em cada página + per_page_code_head: "Código a ser incluído em cada página ()" + per_page_code_body: "Código a ser incluído em cada página ()" proposal_code_prefix: Prefixo para códigos de Proposta votes_for_proposal_success: Número de votos necessários para aprovar uma Proposta shared: diff --git a/config/locales/settings.en.yml b/config/locales/settings.en.yml index 811f10557..7e126bc35 100755 --- a/config/locales/settings.en.yml +++ b/config/locales/settings.en.yml @@ -13,7 +13,8 @@ en: votes_for_proposal_success: "Number of votes necessary for approval of a Proposal" months_to_archive_proposals: "Months to archive Proposals" email_domain_for_officials: "Email domain for public officials" - per_page_code: "Code to be included on every page" + per_page_code_head: "Code to be included on every page ()" + per_page_code_body: "Code to be included on every page ()" twitter_handle: "Twitter handle" twitter_hashtag: "Twitter hashtag" facebook_handle: "Facebook handle" diff --git a/config/locales/settings.es.yml b/config/locales/settings.es.yml index b4575432e..27224d90b 100644 --- a/config/locales/settings.es.yml +++ b/config/locales/settings.es.yml @@ -13,7 +13,8 @@ es: votes_for_proposal_success: "Número de votos necesarios para aprobar una Propuesta" months_to_archive_proposals: "Meses para archivar las Propuestas" email_domain_for_officials: "Dominio de email para cargos públicos" - per_page_code: "Código a incluir en cada página" + per_page_code_head: "Código a incluir en cada página ()" + per_page_code_body: "Código a incluir en cada página ()" twitter_handle: "Usuario de Twitter" twitter_hashtag: "Hashtag para Twitter" facebook_handle: "Identificador de Facebook" diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index a59a3c9b9..7ad046c42 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -32,7 +32,8 @@ Setting.create(key: 'feature.twitter_login', value: "true") Setting.create(key: 'feature.facebook_login', value: "true") Setting.create(key: 'feature.google_login', value: "true") Setting.create(key: 'feature.signature_sheets', value: "true") -Setting.create(key: 'per_page_code', value: "") +Setting.create(key: 'per_page_code_head', value: "") +Setting.create(key: 'per_page_code_body', value: "") Setting.create(key: 'comments_body_max_length', value: '1000') Setting.create(key: 'mailer_from_name', value: 'Consul') Setting.create(key: 'mailer_from_address', value: 'noreply@consul.dev') diff --git a/db/seeds.rb b/db/seeds.rb index 41261d9d7..5ff079f2f 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -38,8 +38,11 @@ Setting["months_to_archive_proposals"] = 12 # Emails under the domain's subdomains will also be included Setting["email_domain_for_officials"] = '' -# Code to be included at the top (header) of every page (useful for tracking) -Setting['per_page_code'] = '' +# Code to be included at the top (inside ) of every page (useful for tracking) +Setting['per_page_code_head'] = '' + +# Code to be included at the top (inside ) of every page +Setting['per_page_code_body'] = '' # Social settings Setting["twitter_handle"] = nil From dadfdba1b1fd34b74e54da63c0aafa611518ba83 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 20 Mar 2017 11:59:22 +0100 Subject: [PATCH 480/613] adds date of birth form when manager creates new user --- app/controllers/management/users_controller.rb | 2 +- app/views/management/users/new.html.erb | 10 ++++++++-- config/locales/management.en.yml | 1 + config/locales/management.es.yml | 1 + spec/features/management/users_spec.rb | 2 ++ 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/controllers/management/users_controller.rb b/app/controllers/management/users_controller.rb index 53004a838..8d3d148fa 100644 --- a/app/controllers/management/users_controller.rb +++ b/app/controllers/management/users_controller.rb @@ -32,7 +32,7 @@ class Management::UsersController < Management::BaseController private def user_params - params.require(:user).permit(:document_type, :document_number, :username, :email) + params.require(:user).permit(:document_type, :document_number, :username, :email, :date_of_birth) end def destroy_session diff --git a/app/views/management/users/new.html.erb b/app/views/management/users/new.html.erb index 6602e4978..d52597590 100644 --- a/app/views/management/users/new.html.erb +++ b/app/views/management/users/new.html.erb @@ -4,7 +4,7 @@ message: t("management.document_verifications.in_census_has_following_permissions"), permissions: [:debates, :create_proposals, :support_proposals, :vote_proposals] %> -
    +
    NavegadorAcción a realizar NavegadorAcción a realizar
    - - + + + + <% @budgets.each do |budget| %> From 841364efc09e09de6bd48e1b566d6ddca179b07c Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 22 Mar 2017 17:14:36 +0100 Subject: [PATCH 488/613] adds th scope --- app/views/budgets/index.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/budgets/index.html.erb b/app/views/budgets/index.html.erb index 79bba8d2c..f3e386d27 100644 --- a/app/views/budgets/index.html.erb +++ b/app/views/budgets/index.html.erb @@ -11,8 +11,8 @@
    <%= Budget.human_attribute_name(:name) %><%= Budget.human_attribute_name(:phase) %>
    <%= Budget.human_attribute_name(:name) %><%= Budget.human_attribute_name(:phase) %>
    - - + + From 53290b3d0d7f0b8266b4cee25a5308e8997df613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 23 Mar 2017 12:48:00 +0100 Subject: [PATCH 489/613] renames budget phases --- config/locales/activerecord.es.yml | 8 ++++---- config/locales/budgets.en.yml | 10 +++++----- config/locales/budgets.es.yml | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index c71a34178..7d47a8e30 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -43,13 +43,13 @@ es: attributes: budget: name: "Nombre" - description_accepting: "Descripción durante la fase de aceptación" - description_reviewing: "Descripción durante la fase de revisión" - description_selecting: "Descripción durante la fase de selección" + description_accepting: "Descripción durante la fase de presentación de proyectos" + description_reviewing: "Descripción durante la fase de revisión interna" + description_selecting: "Descripción durante la fase de apoyos" description_valuating: "Descripción durante la fase de evaluación" description_balloting: "Descripción durante la fase de votación" description_reviewing_ballots: "Descripción durante la fase de revisión de votos" - description_finished: "Descripción cuando el presupuesto ha finalizado" + description_finished: "Descripción cuando el presupuesto ha finalizado / Resultados" phase: "Fase" currency_symbol: "Divisa" budget/investment: diff --git a/config/locales/budgets.en.yml b/config/locales/budgets.en.yml index 5e4861a16..7b3251ad4 100644 --- a/config/locales/budgets.en.yml +++ b/config/locales/budgets.en.yml @@ -25,11 +25,11 @@ en: unfeasible_title: Unfeasible investments unfeasible: See unfeasible investments phase: - accepting: Accepting proposals - reviewing: Reviewing proposals - selecting: Selecting proposals - valuating: Valuating proposals - balloting: Balloting proposals + accepting: Accepting projects + reviewing: Reviewing projects + selecting: Selecting projects + valuating: Valuating projects + balloting: Balloting projects reviewing_ballots: Reviewing Ballots finished: Finished budget index: diff --git a/config/locales/budgets.es.yml b/config/locales/budgets.es.yml index 08a33bde8..44b748698 100644 --- a/config/locales/budgets.es.yml +++ b/config/locales/budgets.es.yml @@ -25,13 +25,13 @@ es: unfeasible_title: Propuestas inviables unfeasible: Ver propuestas inviables phase: - accepting: Aceptando propuestas - reviewing: Revisando propuestas - selecting: Selección de propuestas - valuating: Evaluación de propuestas - balloting: Votación de propuestas - reviewing_ballots: Contando resultados - finished: Presupuesto terminado + accepting: Presentación de proyectos + reviewing: Revisión interna de proyectos + selecting: Fase de apoyos + valuating: Evaluación de proyectos + balloting: Votación final + reviewing_ballots: Votación finalizada + finished: Resultados index: title: Presupuestos participativos investments: From d2129bf9262423b73f0e7b88afe589083339fb4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 23 Mar 2017 13:06:09 +0100 Subject: [PATCH 490/613] fixes spec --- spec/features/admin/budgets_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 3b34878af..c93aebea1 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -84,7 +84,7 @@ feature 'Admin budgets' do fill_in 'budget_name', with: 'M30 - Summer campaign' fill_in 'budget_description_accepting', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30' - select 'Accepting proposals', from: 'budget[phase]' + select 'Accepting projects', from: 'budget[phase]' click_button 'Create Participatory budget' From 4da66e3f5113e440eef94b8dedb6424e1b6462b3 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 24 Mar 2017 13:49:56 +0100 Subject: [PATCH 491/613] Show should display supports --- app/models/budget/investment.rb | 2 +- spec/features/budgets/investments_spec.rb | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 230e25d82..99e0eb25a 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -225,7 +225,7 @@ class Budget def should_show_aside? (budget.selecting? && !unfeasible?) || (budget.balloting? && feasible?) || - (budget.valuating? && feasible?) + (budget.valuating? && !unfeasible?) end def should_show_votes? diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 1d812bd7e..5446e0a0a 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -405,7 +405,7 @@ feature 'Budget Investments' do budget.update(phase: "valuating") end - scenario "Sidebar in show should display supports text and supports" do + scenario "Sidebar in show should display support text and count" do investment = create(:budget_investment, :selected, budget: budget) create(:vote, votable: investment) @@ -417,8 +417,8 @@ feature 'Budget Investments' do end end - scenario "Index should display supports" do - investment = create(:budget_investment, :selected, budget: budget, heading: heading) + scenario "Index should display support count" do + investment = create(:budget_investment, budget: budget, heading: heading) create(:vote, votable: investment) visit budget_investments_path(budget, heading_id: heading.id) @@ -428,6 +428,18 @@ feature 'Budget Investments' do end end + scenario "Show should display support text and count" do + investment = create(:budget_investment, budget: budget, heading: heading) + create(:vote, votable: investment) + + visit budget_investment_path(budget, investment) + + within("#budget_investment_#{investment.id}") do + expect(page).to have_content "Supports" + expect(page).to have_content "1 support" + end + end + end context "Balloting Phase" do From 386f935cc6256c77ee89194eb7dc58ccd667c9af Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 24 Mar 2017 15:24:37 +0100 Subject: [PATCH 492/613] displays link to valuation section --- app/views/shared/_admin_login_items.html.erb | 3 ++- spec/features/valuation/budget_investments_spec.rb | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/views/shared/_admin_login_items.html.erb b/app/views/shared/_admin_login_items.html.erb index 013320f38..1d7c7f188 100644 --- a/app/views/shared/_admin_login_items.html.erb +++ b/app/views/shared/_admin_login_items.html.erb @@ -11,7 +11,8 @@ <% end %> - <% if feature?(:spending_proposals) && (current_user.administrator? || current_user.valuator?) %> + <% if (feature?(:spending_proposals) || feature?(:budgets)) && + (current_user.administrator? || current_user.valuator?) %>
  • <%= link_to t("layouts.header.valuation"), valuation_root_path %>
  • diff --git a/spec/features/valuation/budget_investments_spec.rb b/spec/features/valuation/budget_investments_spec.rb index bac7d1fe2..f6e930cc6 100644 --- a/spec/features/valuation/budget_investments_spec.rb +++ b/spec/features/valuation/budget_investments_spec.rb @@ -13,6 +13,12 @@ feature 'Valuation budget investments' do expect{ visit valuation_budget_budget_investments_path(create(:budget)) }.to raise_exception(FeatureFlags::FeatureDisabled) end + scenario 'Display link to valuation section' do + Setting['feature.budgets'] = true + visit root_path + expect(page).to have_link "Valuation", href: valuation_root_path + end + scenario 'Index shows budget investments assigned to current valuator' do investment1 = create(:budget_investment, budget: @budget) investment2 = create(:budget_investment, budget: @budget) From 8c19802dc6828f55e5a3cfb17ab8f320a6454c01 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 24 Mar 2017 15:24:57 +0100 Subject: [PATCH 493/613] updates dev seeds for valuators --- 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 7ad046c42..eb1651a0c 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -391,7 +391,7 @@ end puts "Creating Valuation Assignments" -(1..17).to_a.sample.times do +(1..50).to_a.sample.times do Budget::Investment.reorder("RANDOM()").first.valuators << valuator.valuator end From 7523c4f870234a5e60b56494bc68a250fad48818 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 24 Mar 2017 16:21:56 +0100 Subject: [PATCH 494/613] adds missing close div tag --- app/views/devise/confirmations/new.html.erb | 1 + app/views/devise/passwords/new.html.erb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb index fe2cf0dc5..51f6cf1eb 100644 --- a/app/views/devise/confirmations/new.html.erb +++ b/app/views/devise/confirmations/new.html.erb @@ -19,6 +19,7 @@ <%= f.submit(t("devise_views.confirmations.new.submit"), class: "button expanded") %> + <% end %> <%= render "devise/shared/links" %> diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb index 72dd70fb9..b06c9ff25 100644 --- a/app/views/devise/passwords/new.html.erb +++ b/app/views/devise/passwords/new.html.erb @@ -11,6 +11,7 @@ <%= f.submit t("devise_views.passwords.new.send_submit"), class: "button expanded" %> + <% end %> <%= render "devise/shared/links" %> From 865a9e78a4693e977e24bc3e39a155a302f01835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 24 Mar 2017 21:32:51 +0100 Subject: [PATCH 495/613] updates runtime dependencies --- Gemfile | 16 ++++----- Gemfile.lock | 98 ++++++++++++++++++++++++++++------------------------ 2 files changed, 61 insertions(+), 53 deletions(-) diff --git a/Gemfile b/Gemfile index 262a44ba4..06d66c0ba 100644 --- a/Gemfile +++ b/Gemfile @@ -3,18 +3,18 @@ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2.8' # Use PostgreSQL -gem 'pg', '~> 0.19.0' +gem 'pg', '~> 0.20.0' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0', '>= 5.0.4' # Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '~> 3.1.6' +gem 'uglifier', '~> 3.1.9' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2.1' # See https://github.com/rails/execjs#readme for more supported runtimes # gem 'therubyracer', platforms: :ruby # Use jquery as the JavaScript library -gem 'jquery-rails', '~> 4.2.2' +gem 'jquery-rails', '~> 4.3.1' gem 'jquery-ui-rails' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks gem 'turbolinks' @@ -28,10 +28,10 @@ gem 'devise_security_extension' # gem 'bcrypt', '~> 3.1.7' gem 'omniauth' gem 'omniauth-twitter' -gem 'omniauth-facebook', '~> 3.0.0' +gem 'omniauth-facebook', '~> 4.0.0' gem 'omniauth-google-oauth2', '~> 0.4.0' -gem 'kaminari' +gem 'kaminari', '~> 1.0.1' gem 'ancestry', '~> 2.2.2' gem 'acts-as-taggable-on' gem 'responders', '~> 2.3.0' @@ -48,16 +48,16 @@ gem 'paranoia', '~> 2.2.1' gem 'rinku', '~> 2.0.2', require: 'rails_rinku' gem 'savon' gem 'dalli' -gem 'rollbar', '~> 2.14.0' +gem 'rollbar', '~> 2.14.1' gem 'delayed_job_active_record', '~> 4.1.0' gem 'daemons' gem 'devise-async' -gem 'newrelic_rpm', '~> 3.18.1.330' +gem 'newrelic_rpm', '~> 4.0.0.332' gem 'whenever', require: false gem 'pg_search' gem 'sitemap_generator', '~> 5.3.1' -gem 'ahoy_matey', '~> 1.5.3' +gem 'ahoy_matey', '~> 1.5.5' gem 'groupdate', '~> 3.2.0' # group temporary data gem 'tolk', '~> 2.0.0' # Web interface for translations diff --git a/Gemfile.lock b/Gemfile.lock index 738087adf..2690d8afa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -35,12 +35,12 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - acts-as-taggable-on (3.5.0) - activerecord (>= 3.2, < 5) + acts-as-taggable-on (4.0.0) + activerecord (>= 4.0) acts_as_votable (0.10.0) addressable (2.5.0) public_suffix (~> 2.0, >= 2.0.2) - ahoy_matey (1.5.4) + ahoy_matey (1.5.5) addressable browser (~> 2.0) geocoder @@ -110,8 +110,8 @@ GEM coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.10.0) - concurrent-ruby (1.0.4) + coffee-script-source (1.12.2) + concurrent-ruby (1.0.5) coveralls (0.8.19) json (>= 1.8, < 3) simplecov (~> 0.12.0) @@ -159,7 +159,7 @@ GEM railties (>= 3.0.0) faker (1.7.3) i18n (~> 0.5) - faraday (0.9.2) + faraday (0.11.0) multipart-post (>= 1.2, < 3) foundation-rails (6.2.4.0) railties (>= 3.1.0) @@ -181,7 +181,7 @@ GEM activesupport (>= 3) gyoku (1.3.1) builder (>= 2.1.2) - hashie (3.4.6) + hashie (3.5.5) highline (1.7.8) htmlentities (4.3.4) httpi (2.4.1) @@ -201,17 +201,26 @@ GEM railties (>= 3.1, < 6.0) invisible_captcha (0.9.2) rails (>= 3.2.0) - jquery-rails (4.2.2) + jquery-rails (4.3.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (5.0.5) + jquery-ui-rails (6.0.1) railties (>= 3.2.16) - json (1.8.6) - jwt (1.5.4) - kaminari (0.17.0) - actionpack (>= 3.0.0) - activesupport (>= 3.0.0) + json (2.0.3) + jwt (1.5.6) + kaminari (1.0.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.0.1) + kaminari-activerecord (= 1.0.1) + kaminari-core (= 1.0.1) + kaminari-actionview (1.0.1) + actionview + kaminari-core (= 1.0.1) + kaminari-activerecord (1.0.1) + activerecord + kaminari-core (= 1.0.1) + kaminari-core (1.0.1) kgio (2.11.0) knapsack (1.13.1) rake @@ -234,26 +243,26 @@ GEM mini_portile2 (2.1.0) minitest (5.10.1) multi_json (1.12.1) - multi_xml (0.5.5) + multi_xml (0.6.0) multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (4.1.0) - newrelic_rpm (3.18.1.330) - nokogiri (1.7.0.1) + newrelic_rpm (4.0.0.332) + nokogiri (1.7.1) mini_portile2 (~> 2.1.0) nori (2.6.0) - oauth (0.5.0) - oauth2 (1.0.0) - faraday (>= 0.8, < 0.10) + oauth (0.5.1) + oauth2 (1.3.1) + faraday (>= 0.8, < 0.12) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) - rack (~> 1.2) - omniauth (1.3.1) - hashie (>= 1.2, < 4) - rack (>= 1.0, < 3) - omniauth-facebook (3.0.0) + rack (>= 1.2, < 3) + omniauth (1.6.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) + omniauth-facebook (4.0.0) omniauth-oauth2 (~> 1.2) omniauth-google-oauth2 (0.4.1) jwt (~> 1.5.2) @@ -266,19 +275,19 @@ GEM omniauth-oauth2 (1.4.0) oauth2 (~> 1.0) omniauth (~> 1.2) - omniauth-twitter (1.2.1) - json (~> 1.3) + omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) + rack orm_adapter (0.5.0) paranoia (2.2.1) activerecord (>= 4.0, < 5.1) parser (2.4.0.0) ast (~> 2.2) - pg (0.19.0) - pg_search (1.0.6) - activerecord (>= 3.1) - activesupport (>= 3.1) - arel + pg (0.20.0) + pg_search (2.0.1) + activerecord (>= 4.2) + activesupport (>= 4.2) + arel (>= 6) poltergeist (1.13.0) capybara (~> 2.1) cliver (~> 0.3.1) @@ -327,7 +336,7 @@ GEM responders (2.3.0) railties (>= 4.2.0, < 5.1) rinku (2.0.2) - rollbar (2.14.0) + rollbar (2.14.1) multi_json rspec-core (3.5.4) rspec-support (~> 3.5.0) @@ -359,7 +368,7 @@ GEM safe_yaml (1.0.4) safely_block (0.2.0) errbase - sass (3.4.22) + sass (3.4.23) sass-rails (5.0.6) railties (>= 4.0.0, < 6) sass (~> 3.1) @@ -381,9 +390,8 @@ GEM simplecov-html (0.10.0) sitemap_generator (5.3.1) builder (~> 3.0) - social-share-button (0.3.1) + social-share-button (0.10.0) coffee-rails - sass-rails spring (1.7.2) spring-commands-rspec (1.0.4) spring (>= 0.9.1) @@ -408,7 +416,7 @@ GEM thor (0.19.4) thread (0.2.2) thread_safe (0.3.6) - tilt (2.0.5) + tilt (2.0.7) timecop (0.8.1) tins (1.13.2) tolk (2.0.0) @@ -423,7 +431,7 @@ GEM tilt (>= 1.4, < 3) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (3.1.6) + uglifier (3.1.9) execjs (>= 0.3.0, < 3) unicode-display_width (1.1.3) unicorn (5.2.0) @@ -455,7 +463,7 @@ PLATFORMS DEPENDENCIES acts-as-taggable-on acts_as_votable - ahoy_matey (~> 1.5.3) + ahoy_matey (~> 1.5.5) ancestry (~> 2.2.2) browser bullet (~> 5.5.1) @@ -486,19 +494,19 @@ DEPENDENCIES i18n-tasks (~> 0.9.12) initialjs-rails (= 0.2.0.4) invisible_captcha (~> 0.9.2) - jquery-rails (~> 4.2.2) + jquery-rails (~> 4.3.1) jquery-ui-rails - kaminari + kaminari (~> 1.0.1) knapsack launchy letter_opener_web (~> 1.3.1) - newrelic_rpm (~> 3.18.1.330) + newrelic_rpm (~> 4.0.0.332) omniauth - omniauth-facebook (~> 3.0.0) + omniauth-facebook (~> 4.0.0) omniauth-google-oauth2 (~> 0.4.0) omniauth-twitter paranoia (~> 2.2.1) - pg (~> 0.19.0) + pg (~> 0.20.0) pg_search poltergeist (~> 1.13.0) quiet_assets @@ -506,7 +514,7 @@ DEPENDENCIES redcarpet (~> 3.4.0) responders (~> 2.3.0) rinku (~> 2.0.2) - rollbar (~> 2.14.0) + rollbar (~> 2.14.1) rspec-rails (~> 3.5) rubocop (~> 0.47.1) rvm1-capistrano3 From 18bce501ce42e3f07bfdd1c602f7b6658534a7fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 24 Mar 2017 21:40:30 +0100 Subject: [PATCH 496/613] updates development dependencies --- Gemfile | 6 +++--- Gemfile.lock | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Gemfile b/Gemfile index 06d66c0ba..831b62813 100644 --- a/Gemfile +++ b/Gemfile @@ -72,14 +72,14 @@ group :development, :test do gem 'spring' gem 'spring-commands-rspec' gem 'rspec-rails', '~> 3.5' - gem 'capybara', '~> 2.12.1' + gem 'capybara', '~> 2.13.0' gem 'factory_girl_rails', '~> 4.8.0' gem 'fuubar' gem 'launchy' gem 'quiet_assets' gem 'letter_opener_web', '~> 1.3.1' gem 'i18n-tasks', '~> 0.9.12' - gem 'capistrano', '~> 3.7.2', require: false + gem 'capistrano', '~> 3.8.0', require: false gem 'capistrano-bundler', '~> 1.2', require: false gem "capistrano-rails", '~> 1.2.3', require: false gem 'rvm1-capistrano3', require: false @@ -92,7 +92,7 @@ end group :test do gem 'database_cleaner' - gem 'poltergeist', '~> 1.13.0' + gem 'poltergeist', '~> 1.14.0' gem 'coveralls', '~> 0.8.19', require: false gem 'email_spec' end diff --git a/Gemfile.lock b/Gemfile.lock index 2690d8afa..c9d097a15 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,23 +72,21 @@ GEM uniform_notifier (~> 1.10.0) byebug (9.0.6) cancancan (1.16.0) - capistrano (3.7.2) + capistrano (3.8.0) airbrussh (>= 1.0.0) - capistrano-harrow i18n rake (>= 10.0.0) sshkit (>= 1.9.0) capistrano-bundler (1.2.0) capistrano (~> 3.1) sshkit (~> 1.2) - capistrano-harrow (0.5.3) capistrano-rails (1.2.3) capistrano (~> 3.1) capistrano-bundler (~> 1.1) capistrano3-delayed-job (1.7.3) capistrano (~> 3.0, >= 3.0.0) daemons (~> 1.2.4) - capybara (2.12.1) + capybara (2.13.0) addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -222,7 +220,7 @@ GEM kaminari-core (= 1.0.1) kaminari-core (1.0.1) kgio (2.11.0) - knapsack (1.13.1) + knapsack (1.13.2) rake timecop (>= 0.1.0) launchy (2.4.3) @@ -288,7 +286,7 @@ GEM activerecord (>= 4.2) activesupport (>= 4.2) arel (>= 6) - poltergeist (1.13.0) + poltergeist (1.14.0) capybara (~> 2.1) cliver (~> 0.3.1) websocket-driver (>= 0.2.0) @@ -392,7 +390,8 @@ GEM builder (~> 3.0) social-share-button (0.10.0) coffee-rails - spring (1.7.2) + spring (2.0.1) + activesupport (>= 4.2) spring-commands-rspec (1.0.4) spring (>= 0.9.1) sprockets (3.7.1) @@ -469,11 +468,11 @@ DEPENDENCIES bullet (~> 5.5.1) byebug cancancan (~> 1.16.0) - capistrano (~> 3.7.2) + capistrano (~> 3.8.0) capistrano-bundler (~> 1.2) capistrano-rails (~> 1.2.3) capistrano3-delayed-job (~> 1.7.3) - capybara (~> 2.12.1) + capybara (~> 2.13.0) ckeditor (~> 4.2.2) coffee-rails (~> 4.2.1) coveralls (~> 0.8.19) @@ -508,7 +507,7 @@ DEPENDENCIES paranoia (~> 2.2.1) pg (~> 0.20.0) pg_search - poltergeist (~> 1.13.0) + poltergeist (~> 1.14.0) quiet_assets rails (= 4.2.8) redcarpet (~> 3.4.0) @@ -528,7 +527,7 @@ DEPENDENCIES tolk (~> 2.0.0) turbolinks turnout (~> 2.4.0) - uglifier (~> 3.1.6) + uglifier (~> 3.1.9) unicorn (~> 5.2.0) web-console (= 3.3.0) whenever From 3f15565f9e376ac5d6c670f1371f26d0ea95d6f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 24 Mar 2017 22:02:34 +0100 Subject: [PATCH 497/613] uses new jquery-ui widgets path in require --- app/assets/javascripts/application.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index fba539eeb..78c5c7444 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,8 +12,8 @@ // //= require jquery //= require jquery_ujs -//= require jquery-ui/datepicker -//= require jquery-ui/datepicker-es +//= require jquery-ui/widgets/datepicker +//= require jquery-ui/i18n/datepicker-es //= require foundation //= require turbolinks //= require ckeditor/loader From 4191d66ed4dd0c793066da506267b39445a525e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Sat, 25 Mar 2017 12:11:05 +0100 Subject: [PATCH 498/613] fixes datepicker in advanced search --- app/views/shared/_advanced_search.html.erb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/views/shared/_advanced_search.html.erb b/app/views/shared/_advanced_search.html.erb index 56157c4a7..558adc806 100644 --- a/app/views/shared/_advanced_search.html.erb +++ b/app/views/shared/_advanced_search.html.erb @@ -36,7 +36,6 @@ <%= text_field_tag 'advanced_search[date_min]', params[:advanced_search].try(:[], :date_min), - type: "date", class: 'js-calendar' %>
    @@ -45,7 +44,6 @@ <%= text_field_tag 'advanced_search[date_max]', params[:advanced_search].try(:[], :date_max), - type: "date", class: 'js-calendar' %>
    From 652aff4e19e79a751c491d7b0841d4da0403cd4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 27 Mar 2017 12:18:45 +0200 Subject: [PATCH 499/613] adds validation for custom dates in advanced search avoids error 500 on invalid dates --- .../concerns/commentable_actions.rb | 6 ++--- spec/features/debates_spec.rb | 22 +++++++++++++++++++ spec/features/proposals_spec.rb | 22 +++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/app/controllers/concerns/commentable_actions.rb b/app/controllers/concerns/commentable_actions.rb index ef5e60dcb..ee69ac809 100644 --- a/app/controllers/concerns/commentable_actions.rb +++ b/app/controllers/concerns/commentable_actions.rb @@ -129,16 +129,16 @@ module CommentableActions when '4' 1.year.ago else - Date.parse(params[:advanced_search][:date_min]) rescue nil + Date.parse(params[:advanced_search][:date_min]) rescue 100.years.ago end end def search_finish_date - params[:advanced_search][:date_max].try(:to_date) || Date.today + (params[:advanced_search][:date_max].to_date rescue Date.today) || Date.today end def search_date_range - search_start_date.beginning_of_day..search_finish_date.end_of_day + [100.years.ago, search_start_date].max.beginning_of_day..[search_finish_date, Date.today].min.end_of_day end def set_search_order diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index f16f416bf..bc01c94e2 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -640,6 +640,28 @@ feature 'Debates' do end end + scenario "Search by custom invalid date range", :js do + debate1 = create(:debate, created_at: 2.years.ago) + debate2 = create(:debate, created_at: 3.days.ago) + debate3 = create(:debate, created_at: 9.days.ago) + + visit debates_path + + click_link "Advanced search" + select "Customized", from: "js-advanced-search-date-min" + fill_in "advanced_search_date_min", with: "9" + fill_in "advanced_search_date_max", with: "444444444" + click_button "Filter" + + within("#debates") do + expect(page).to have_css('.debate', count: 3) + + expect(page).to have_content(debate1.title) + expect(page).to have_content(debate2.title) + expect(page).to have_content(debate3.title) + end + end + scenario "Search by multiple filters", :js do ana = create :user, official_level: 1 john = create :user, official_level: 1 diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 18864dc9b..dbc5956cd 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -980,6 +980,28 @@ feature 'Proposals' do end end + scenario "Search by custom invalid date range", :js do + proposal1 = create(:proposal, created_at: 2.days.ago) + proposal2 = create(:proposal, created_at: 3.days.ago) + proposal3 = create(:proposal, created_at: 9.days.ago) + + visit proposals_path + + click_link "Advanced search" + select "Customized", from: "js-advanced-search-date-min" + fill_in "advanced_search_date_min", with: 4000.years.ago + fill_in "advanced_search_date_max", with: "wrong date" + click_button "Filter" + + expect(page).to have_content("There are 3 citizen proposals") + + within("#proposals") do + expect(page).to have_content(proposal1.title) + expect(page).to have_content(proposal2.title) + expect(page).to have_content(proposal3.title) + end + end + scenario "Search by multiple filters", :js do ana = create :user, official_level: 1 john = create :user, official_level: 1 From 3c2ab9fb056720adf056abb824db154d3130996b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 27 Mar 2017 13:14:26 +0200 Subject: [PATCH 500/613] adds validation for price when investment is feasible --- app/models/budget/investment.rb | 5 +++++ spec/models/budget/investment_spec.rb | 25 ++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 99e0eb25a..4bfd038c3 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -25,6 +25,7 @@ class Budget validates :description, presence: true validates :heading_id, presence: true validates_presence_of :unfeasibility_explanation, if: :unfeasibility_explanation_required? + validates_presence_of :price, if: :price_required? validates :title, length: { in: 4..Budget::Investment.title_max_length } validates :description, length: { maximum: Budget::Investment.description_max_length } @@ -136,6 +137,10 @@ class Budget unfeasible? && valuation_finished? end + def price_required? + feasible? && valuation_finished? + end + def unfeasible_email_pending? unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished? end diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index 3ab97c574..fa51f3cab 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -54,7 +54,7 @@ describe Budget::Investment do expect(investment.group_id).to eq group_2.id end - describe "#unfeasibility_explanation" do + describe "#unfeasibility_explanation blank" do it "should be valid if valuation not finished" do investment.unfeasibility_explanation = "" investment.valuation_finished = false @@ -76,6 +76,29 @@ describe Budget::Investment do end end + describe "#price blank" do + it "should be valid if valuation not finished" do + investment.price = "" + investment.valuation_finished = false + expect(investment).to be_valid + end + + it "should be valid if valuation finished and unfeasible" do + investment.price = "" + investment.unfeasibility_explanation = "reason" + investment.feasibility = "unfeasible" + investment.valuation_finished = true + expect(investment).to be_valid + end + + it "should not be valid if valuation finished and feasible" do + investment.price = "" + investment.feasibility = "feasible" + investment.valuation_finished = true + expect(investment).to_not be_valid + end + end + describe "#code" do let(:investment) { create(:budget_investment) } From d9d38482b34ad7079743b485e807260a9ab300cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 27 Mar 2017 13:56:16 +0200 Subject: [PATCH 501/613] extends Activity to include Investment valuations --- app/models/activity.rb | 3 ++- spec/models/activity_spec.rb | 16 ++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/models/activity.rb b/app/models/activity.rb index 047ccb7dd..0fc35ad11 100644 --- a/app/models/activity.rb +++ b/app/models/activity.rb @@ -2,7 +2,7 @@ class Activity < ActiveRecord::Base belongs_to :actionable, -> { with_hidden }, polymorphic: true belongs_to :user, -> { with_hidden } - VALID_ACTIONS = %w( hide block restore ) + VALID_ACTIONS = %w( hide block restore valuate ) validates :action, inclusion: {in: VALID_ACTIONS} @@ -10,6 +10,7 @@ class Activity < ActiveRecord::Base scope :on_debates, -> { where(actionable_type: 'Debate') } scope :on_users, -> { where(actionable_type: 'User') } scope :on_comments, -> { where(actionable_type: 'Comment') } + scope :on_budget_investments, -> { where(actionable_type: 'Budget::Investment') } scope :for_render, -> { includes(user: [:moderator, :administrator]).includes(:actionable) } def self.log(user, action, actionable) diff --git a/spec/models/activity_spec.rb b/spec/models/activity_spec.rb index 0c7b99027..44ecc6ffd 100644 --- a/spec/models/activity_spec.rb +++ b/spec/models/activity_spec.rb @@ -56,11 +56,12 @@ describe Activity do activity3 = create(:activity, user: user1, action: "hide", actionable: create(:proposal)) activity4 = create(:activity, user: user1, action: "hide", actionable: create(:comment)) activity5 = create(:activity, user: user1, action: "block", actionable: create(:user)) + activity6 = create(:activity, user: user1, action: "valuate", actionable: create(:budget_investment)) create_list(:activity, 3) - expect(Activity.by(user1).size).to eq 5 + expect(Activity.by(user1).size).to eq 6 - [activity1, activity2, activity3, activity4, activity5].each do |a| + [activity1, activity2, activity3, activity4, activity5, activity6].each do |a| expect(Activity.by(user1)).to include(a) end end @@ -68,20 +69,23 @@ describe Activity do describe "scopes by actionable" do it "should filter by actionable type" do - on_proposal = create(:activity, actionable: create(:proposal)) - on_debate = create(:activity, actionable: create(:debate)) - on_comment = create(:activity, actionable: create(:comment)) - on_user = create(:activity, actionable: create(:user)) + on_proposal = create(:activity, actionable: create(:proposal)) + on_debate = create(:activity, actionable: create(:debate)) + on_comment = create(:activity, actionable: create(:comment)) + on_user = create(:activity, actionable: create(:user)) + on_investment = create(:activity, actionable: create(:budget_investment)) expect(Activity.on_proposals.size).to eq 1 expect(Activity.on_debates.size).to eq 1 expect(Activity.on_comments.size).to eq 1 expect(Activity.on_users.size).to eq 1 + expect(Activity.on_budget_investments.size).to eq 1 expect(Activity.on_proposals.first).to eq on_proposal expect(Activity.on_debates.first).to eq on_debate expect(Activity.on_comments.first).to eq on_comment expect(Activity.on_users.first).to eq on_user + expect(Activity.on_budget_investments.first).to eq on_investment end end From c86cdb5d9be88cf859b66ffc7b4d9e50023ea55f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 27 Mar 2017 13:56:55 +0200 Subject: [PATCH 502/613] logs valuators activity --- app/controllers/valuation/budget_investments_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/valuation/budget_investments_controller.rb b/app/controllers/valuation/budget_investments_controller.rb index 666fac74a..ae747464e 100644 --- a/app/controllers/valuation/budget_investments_controller.rb +++ b/app/controllers/valuation/budget_investments_controller.rb @@ -26,6 +26,7 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController @investment.send_unfeasible_email end + Activity.log(current_user, :valuate, @investment) redirect_to valuation_budget_budget_investment_path(@budget, @investment), notice: t('valuation.budget_investments.notice.valuate') else render action: :edit From b4e81d60fc092c8698794d621373e2cc6c175769 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 27 Mar 2017 19:01:39 +0200 Subject: [PATCH 503/613] fixes html validation on whatsapp share --- app/views/budgets/investments/_investment_show.html.erb | 2 +- app/views/debates/show.html.erb | 2 +- app/views/proposals/show.html.erb | 2 +- app/views/spending_proposals/show.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index ebac39186..8b351571f 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -103,7 +103,7 @@
    <%= Budget.human_attribute_name(:name) %><%= Budget.human_attribute_name(:phase) %><%= Budget.human_attribute_name(:name) %><%= Budget.human_attribute_name(:phase) %>
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NombreCreadaÚltima actualizaciónEstado
    + Política de privacidad + + Hace 20 días + + Hace 15 días + + Publicada + + + Ver página + + + Borrar página +
    + FAQ + + Hace 6 días + + Hace 3 días + + + Borrador + + + Ver página + + + Borrar página +
    diff --git a/app/views/sandbox/admin_cms_page.html.erb b/app/views/sandbox/admin_cms_page.html.erb new file mode 100644 index 000000000..625317d35 --- /dev/null +++ b/app/views/sandbox/admin_cms_page.html.erb @@ -0,0 +1,58 @@ + + + + Volver + + +
    +
    +

    Editar Política de privacidad

    + +
    + + + + + + + + + +
    + + +
    +
    +
    +
    +
    +

    Opciones

    + + + +
    + +

    Estado

    + + +
    + + +
    + +
    + + +
    + + +
    + +
    +
    + + From 019037ebddde12e59c7824432fe05de42b03c0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Gonz=C3=A1lez?= Date: Mon, 13 Mar 2017 15:21:22 +0100 Subject: [PATCH 529/613] Add delete page button --- app/views/sandbox/admin_cms_page.html.erb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/sandbox/admin_cms_page.html.erb b/app/views/sandbox/admin_cms_page.html.erb index 625317d35..ea65176b8 100644 --- a/app/views/sandbox/admin_cms_page.html.erb +++ b/app/views/sandbox/admin_cms_page.html.erb @@ -4,7 +4,10 @@ Volver + +
    +

    Editar Política de privacidad

    @@ -19,8 +22,8 @@
    - - + +
    From 255b57cc8520892a4b80a8182bb9acc6ea728ca9 Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Fri, 17 Mar 2017 12:20:36 +0100 Subject: [PATCH 530/613] Admin for custom pages --- .../site_customization/base_controller.rb | 10 +++ .../site_customization/pages_controller.rb | 44 +++++++++++++ app/models/abilities/administrator.rb | 2 + app/models/site_customization.rb | 5 ++ app/models/site_customization/page.rb | 14 +++++ app/views/admin/_menu.html.erb | 6 ++ .../site_customization/pages/_form.html.erb | 52 ++++++++++++++++ .../site_customization/pages/edit.html.erb | 15 +++++ .../site_customization/pages/index.html.erb | 52 ++++++++++++++++ .../site_customization/pages/new.html.erb | 14 +++++ config/locales/activerecord.en.yml | 17 +++++ config/locales/activerecord.es.yml | 17 +++++ config/locales/admin.en.yml | 33 ++++++++++ config/locales/admin.es.yml | 33 ++++++++++ config/routes.rb | 4 ++ ...6174351_create_site_customization_pages.rb | 15 +++++ db/schema.rb | 14 ++++- spec/factories.rb | 18 ++++++ .../admin/site_customization/pages_spec.rb | 62 +++++++++++++++++++ spec/models/site_customization/page_spec.rb | 14 +++++ 20 files changed, 440 insertions(+), 1 deletion(-) create mode 100644 app/controllers/admin/site_customization/base_controller.rb create mode 100644 app/controllers/admin/site_customization/pages_controller.rb create mode 100644 app/models/site_customization.rb create mode 100644 app/models/site_customization/page.rb create mode 100644 app/views/admin/site_customization/pages/_form.html.erb create mode 100644 app/views/admin/site_customization/pages/edit.html.erb create mode 100644 app/views/admin/site_customization/pages/index.html.erb create mode 100644 app/views/admin/site_customization/pages/new.html.erb create mode 100644 db/migrate/20170316174351_create_site_customization_pages.rb create mode 100644 spec/features/admin/site_customization/pages_spec.rb create mode 100644 spec/models/site_customization/page_spec.rb diff --git a/app/controllers/admin/site_customization/base_controller.rb b/app/controllers/admin/site_customization/base_controller.rb new file mode 100644 index 000000000..18422f66e --- /dev/null +++ b/app/controllers/admin/site_customization/base_controller.rb @@ -0,0 +1,10 @@ +class Admin::SiteCustomization::BaseController < Admin::BaseController + helper_method :namespace + + private + + def namespace + "admin" + end + +end diff --git a/app/controllers/admin/site_customization/pages_controller.rb b/app/controllers/admin/site_customization/pages_controller.rb new file mode 100644 index 000000000..0b838054e --- /dev/null +++ b/app/controllers/admin/site_customization/pages_controller.rb @@ -0,0 +1,44 @@ +class Admin::SiteCustomization::PagesController < Admin::SiteCustomization::BaseController + load_and_authorize_resource :page, class: "SiteCustomization::Page" + + def index + @pages = SiteCustomization::Page.order('slug').page(params[:page]) + end + + def create + if @page.save + redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.create.notice', link: @page.slug.html_safe) + else + flash.now[:error] = t('admin.site_customization.pages.create.error') + render :new + end + end + + def update + if @page.update(page_params) + redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.update.notice', link: @page.slug.html_safe) + else + flash.now[:error] = t('admin.site_customization.pages.update.error') + render :edit + end + end + + def destroy + @page.destroy + redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.destroy.notice') + end + + private + + def page_params + params.require(:site_customization_page).permit( + :slug, + :title, + :subtitle, + :content, + :more_info_flag, + :print_content_flag, + :status + ) + end +end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 8e721b2b8..8df9270a3 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -51,6 +51,8 @@ module Abilities can [:search, :edit, :update, :create, :index, :destroy], Banner can [:index, :create, :edit, :update, :destroy], Geozone + + can :manage, SiteCustomization::Page end end end diff --git a/app/models/site_customization.rb b/app/models/site_customization.rb new file mode 100644 index 000000000..e5d2f2137 --- /dev/null +++ b/app/models/site_customization.rb @@ -0,0 +1,5 @@ +module SiteCustomization + def self.table_name_prefix + 'site_customization_' + end +end diff --git a/app/models/site_customization/page.rb b/app/models/site_customization/page.rb new file mode 100644 index 000000000..565e6352a --- /dev/null +++ b/app/models/site_customization/page.rb @@ -0,0 +1,14 @@ +class SiteCustomization::Page < ActiveRecord::Base + VALID_STATUSES = %w(draft published) + + validates :slug, uniqueness: { case_sensitive: false }, + format: { with: /\A[0-9a-zA-Z\-_]*\Z/, message: :slug_format } + validates :title, presence: true + validates :status, presence: true, inclusion: { in: VALID_STATUSES } + + scope :published, -> { where(status: 'published').order('id DESC') } + + def url + "/#{slug}" + end +end diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index d603dbf16..448da1662 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -122,5 +122,11 @@ <%= t("admin.menu.stats") %> <% end %> + +
  • > + <%= link_to admin_site_customization_pages_path do %> + <%= t("admin.menu.site_customization.pages") %> + <% end %> +
  • diff --git a/app/views/admin/site_customization/pages/_form.html.erb b/app/views/admin/site_customization/pages/_form.html.erb new file mode 100644 index 000000000..3881885d2 --- /dev/null +++ b/app/views/admin/site_customization/pages/_form.html.erb @@ -0,0 +1,52 @@ +<%= form_for [:admin, @page], html: {class: "edit_page", data: {watch_changes: true}} do |f| %> + + <% if @page.errors.any? %> + +
    + + + + <%= @page.errors.count %> + <%= t("admin.site_customization.pages.errors.form.error", count: @page.errors.count) %> + +
    + + <% end %> + +
    + + <%= f.label :title %> + <%= f.text_field :title, label: false %> + + <%= f.label :subtitle %> + <%= f.text_field :subtitle, label: false, size: 80, maxlength: 80 %> + + <%= f.label :slug %> + <%= f.text_field :slug, label: false, size: 80, maxlength: 80 %> + +
    + <%= f.label :content %> + <%= f.cktext_area :content, label: false, cols: 80, rows: 10, ckeditor: { language: I18n.locale } %> +
    +
    +
    +
    +

    <%= t("admin.site_customization.pages.form.options") %>

    + <%= f.check_box :more_info_flag %> + <%= f.check_box :print_content_flag %> +
    + +

    <%= f.label :status %>

    + <% ::SiteCustomization::Page::VALID_STATUSES.each do |status| %> + <%= f.radio_button :status, status, label: false %> + <%= f.label "status_#{status}", t("admin.site_customization.pages.status_#{status}") %> +
    + <% end %> + + <%= f.submit class: "button success" %> +
    + +
    +<% end %> diff --git a/app/views/admin/site_customization/pages/edit.html.erb b/app/views/admin/site_customization/pages/edit.html.erb new file mode 100644 index 000000000..c92933cbf --- /dev/null +++ b/app/views/admin/site_customization/pages/edit.html.erb @@ -0,0 +1,15 @@ +<% provide :title do %> + Admin - <%= t("admin.menu.site_customization.pages") %> - <%= @page.title %> +<% end %> + +<%= link_to admin_site_customization_pages_path, class: "back" do %> + + <%= t("admin.site_customization.pages.edit.back") %> +<% end %> + +<%= button_to t("admin.site_customization.pages.index.delete"), admin_site_customization_page_path(@page), method: :delete, class: "button hollow alert float-right margin-right" %> + +
    +

    <%= t("admin.site_customization.pages.edit.title", page_title: @page.title) %>

    + <%= render 'form' %> +
    diff --git a/app/views/admin/site_customization/pages/index.html.erb b/app/views/admin/site_customization/pages/index.html.erb new file mode 100644 index 000000000..356a1813b --- /dev/null +++ b/app/views/admin/site_customization/pages/index.html.erb @@ -0,0 +1,52 @@ +<% provide :title do %> + Admin - <%= t("admin.menu.site_customization.pages") %> +<% end %> + +
    +
    +
    +

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

    +
    +
    + <%= link_to t("admin.site_customization.pages.index.create"), new_admin_site_customization_page_path, class: "button" %> +
    +
    + +

    <%= page_entries_info @pages %>

    + + + + + + + + + + + + + + <% @pages.each do |page| %> + + + + + + + + + <% end %> + +
    <%= t("admin.site_customization.pages.page.title") %><%= t("admin.site_customization.pages.page.created_at") %><%= t("admin.site_customization.pages.page.updated_at") %><%= t("admin.site_customization.pages.page.status") %>
    + <%= link_to page.title, edit_admin_site_customization_page_path(page) %> + <%= I18n.l page.created_at, format: :short %><%= I18n.l page.created_at, format: :short %><%= t("admin.legislation.processes.process.status_#{page.status}") %> + + <%= link_to t("admin.site_customization.pages.index.see_page"), page.url %> + + + <%= link_to t("admin.site_customization.pages.index.delete"), admin_site_customization_page_path(page), method: :delete %> +
    + + <%= paginate @pages %> + +
    diff --git a/app/views/admin/site_customization/pages/new.html.erb b/app/views/admin/site_customization/pages/new.html.erb new file mode 100644 index 000000000..43a86d108 --- /dev/null +++ b/app/views/admin/site_customization/pages/new.html.erb @@ -0,0 +1,14 @@ +<% provide :title do %> + Admin - <%= t("admin.menu.site_customization.pages") %> - <%= t("admin.site_customization.pages.new.title") %> +<% end %> + +<%= link_to admin_site_customization_pages_path, class: "back" do %> + + <%= t("admin.site_customization.pages.new.back") %> +<% end %> + +
    +

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

    + <%= render 'form' %> +
    + diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index 04c5cc9d0..e8354b88e 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -40,6 +40,9 @@ en: spending_proposal: one: "Spending proposal" other: "Spending proposals" + site_customization/page: + one: Custom page + other: Custom pages attributes: budget: name: "Name" @@ -103,6 +106,16 @@ en: signable_type: "Signable type" signable_id: "Signable ID" document_numbers: "Documents numbers" + site_customization/page: + content: Content + created_at: Created at + subtitle: Subtitle + slug: Slug + status: Status + title: Title + updated_at: Updated at + more_info_flag: Show in more information page + print_content_flag: Print content button errors: models: user: @@ -134,3 +147,7 @@ en: document_number: not_in_census: 'Not verified by Census' already_voted: 'Already voted this proposal' + site_customization/page: + attributes: + slug: + slug_format: "must be letters, numbers, _ and -" diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 542406d0a..32b26223b 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -40,6 +40,9 @@ es: spending_proposal: one: "Propuesta de inversión" other: "Propuestas de inversión" + site_customization/page: + one: Página + other: Páginas attributes: budget: name: "Nombre" @@ -98,6 +101,16 @@ es: signable_type: "Tipo de hoja de firmas" signable_id: "ID Propuesta ciudadana/Propuesta inversión" document_numbers: "Números de documentos" + site_customization/page: + content: Contenido + created_at: Creada + subtitle: Subtítulo + slug: Slug + status: Estado + title: Título + updated_at: última actualización + more_info_flag: Mostrar en la página de más información + print_content_flag: Botón de imprimir contenido errors: models: user: @@ -129,3 +142,7 @@ es: document_number: not_in_census: 'No verificado por Padrón' already_voted: 'Ya ha votado esta propuesta' + site_customization/page: + attributes: + slug: + slug_format: "deber ser letras, números, _ y -" diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 460319748..d44179ce8 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -207,6 +207,8 @@ en: spending_proposals: Spending proposals stats: Statistics signature_sheets: Signature Sheets + site_customization: + pages: Custom Pages moderators: index: title: Moderators @@ -475,3 +477,34 @@ en: phone_not_given: Phone not given sms_code_not_confirmed: Has not confirmed the sms code title: Incomplete verifications + site_customization: + pages: + create: + notice: 'Page created successfully.' + error: Process couldn't be created + update: + notice: 'Page updated successfully.' + error: Page couldn't be updated + destroy: + notice: Page deleted successfully + edit: + title: Editing %{page_title} + back: Back + errors: + form: + error: Error + form: + options: Options + index: + create: Create new page + delete: Delete + title: Custom Pages + see_page: See page + new: + back: Back + title: Create new custom page + page: + created_at: Created at + status: Status + title: Title + updated_at: Updated at diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 7d6438416..f93433546 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -207,6 +207,8 @@ es: spending_proposals: Propuestas de inversión stats: Estadísticas signature_sheets: Hojas de firmas + site_customization: + pages: Páginas moderators: index: title: Moderadores @@ -475,3 +477,34 @@ es: phone_not_given: No ha dado su teléfono sms_code_not_confirmed: No ha introducido su código de seguridad title: Verificaciones incompletas + site_customization: + pages: + create: + notice: 'Página creada correctamente.' + error: No se ha podido crear la página + update: + notice: 'Página actualizada correctamente.s' + error: No se ha podido actualizar la página + destroy: + notice: Página eliminada correctamente + edit: + title: Editar %{page_title} + back: Volver + errors: + form: + error: Error + form: + options: Opciones + index: + create: Crear nueva página + delete: Borrar + title: Páginas + see_page: Ver página + new: + back: Back + title: Página nueva + page: + created_at: Creada + status: Estado + title: Título + updated_at: Última actualización diff --git a/config/routes.rb b/config/routes.rb index b1a6d57b2..e31bd86a0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -222,6 +222,10 @@ Rails.application.routes.draw do end resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy] + + namespace :site_customization do + resources :pages + end end namespace :moderation do diff --git a/db/migrate/20170316174351_create_site_customization_pages.rb b/db/migrate/20170316174351_create_site_customization_pages.rb new file mode 100644 index 000000000..3c4fbe846 --- /dev/null +++ b/db/migrate/20170316174351_create_site_customization_pages.rb @@ -0,0 +1,15 @@ +class CreateSiteCustomizationPages < ActiveRecord::Migration + def change + create_table :site_customization_pages do |t| + t.string :slug, null: false + t.string :title, null: false + t.string :subtitle + t.text :content + t.boolean :more_info_flag + t.boolean :print_content_flag + t.string :status, default: 'draft' + + t.timestamps null: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index fb563c8db..0b38a4196 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: 20170316174351) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -439,6 +439,18 @@ ActiveRecord::Schema.define(version: 20170114154421) do t.datetime "updated_at" end + create_table "site_customization_pages", force: :cascade do |t| + t.string "slug", null: false + t.string "title", null: false + t.string "subtitle" + t.text "content" + t.boolean "more_info_flag" + t.boolean "print_content_flag" + t.string "status", default: "draft" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "spending_proposals", force: :cascade do |t| t.string "title" t.text "description" diff --git a/spec/factories.rb b/spec/factories.rb index e058adf15..20a1f463c 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -450,4 +450,22 @@ FactoryGirl.define do signature_sheet sequence(:document_number) { |n| "#{n}A" } end + + factory :site_customization_page, class: 'SiteCustomization::Page' do + slug "example-page" + title "Example page" + subtitle "About an example" + content "This page is about..." + more_info_flag false + print_content_flag false + status 'draft' + + trait :published do + status "published" + end + + trait :display_in_more_info do + more_info_flag true + end + end end diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb new file mode 100644 index 000000000..b9ebeb273 --- /dev/null +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -0,0 +1,62 @@ +require 'rails_helper' + +feature 'Admin custom pages' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + context "Index" do + scenario 'Displaying custom pages' do + custom_page = create(:site_customization_page) + visit admin_site_customization_pages_path + + expect(page).to have_content(custom_page.title) + end + end + + context 'Create' do + scenario 'Valid custom page' do + visit admin_root_path + + within('#side_menu') do + click_link "Custom Pages" + end + + expect(page).to_not have_content 'An example custom page' + + click_link "Create new page" + + fill_in 'site_customization_page_title', with: 'An example custom page' + fill_in 'site_customization_page_subtitle', with: 'Page subtitle' + fill_in 'site_customization_page_slug', with: 'example-page' + fill_in 'site_customization_page_content', with: 'This page is about...' + + click_button 'Create Custom page' + + expect(page).to have_content 'An example custom page' + end + end + + context 'Update' do + scenario 'Valid custom page' do + custom_page = create(:site_customization_page, title: 'An example custom page') + visit admin_root_path + + within('#side_menu') do + click_link "Custom Pages" + end + + click_link "An example custom page" + + expect(page).to have_selector("h2", text: "An example custom page") + + fill_in 'site_customization_page_title', with: 'Another example custom page' + click_button "Update Custom page" + + expect(page).to have_content "Page updated successfully" + expect(page).to have_content 'Another example custom page' + end + end +end diff --git a/spec/models/site_customization/page_spec.rb b/spec/models/site_customization/page_spec.rb new file mode 100644 index 000000000..2868f62d1 --- /dev/null +++ b/spec/models/site_customization/page_spec.rb @@ -0,0 +1,14 @@ +require 'rails_helper' + +RSpec.describe SiteCustomization::Page, type: :model do + let(:custom_page) { build(:site_customization_page) } + + it "should be valid" do + expect(custom_page).to be_valid + end + + it "is invalid if slug has symbols" do + custom_page = build(:site_customization_page, slug: "as/as*la") + expect(custom_page).to be_invalid + end +end From 54fab919e51357c756ec449aa1ee88b22267ad5a Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Fri, 17 Mar 2017 13:36:00 +0100 Subject: [PATCH 531/613] Show custom pages in public site --- app/controllers/pages_controller.rb | 6 +- app/models/site_customization/page.rb | 1 + .../site_customization/pages/index.html.erb | 17 +-- app/views/pages/custom_page.html.erb | 15 +++ app/views/pages/more_info/_other.html.erb | 4 + config/i18n-tasks.yml | 1 + config/locales/admin.en.yml | 2 + config/locales/admin.es.yml | 2 + config/routes.rb | 2 +- .../admin/site_customization/pages_spec.rb | 53 +++++---- .../site_customization/custom_pages_spec.rb | 102 ++++++++++++++++++ 11 files changed, 167 insertions(+), 38 deletions(-) create mode 100644 app/views/pages/custom_page.html.erb create mode 100644 spec/features/site_customization/custom_pages_spec.rb diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 03f62925a..81d6e8dbd 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -2,7 +2,11 @@ class PagesController < ApplicationController skip_authorization_check def show - render action: params[:id] + if @custom_page = SiteCustomization::Page.published.find_by(slug: params[:id]) + render action: :custom_page + else + render action: params[:id] + end rescue ActionView::MissingTemplate head 404 end diff --git a/app/models/site_customization/page.rb b/app/models/site_customization/page.rb index 565e6352a..ea3003465 100644 --- a/app/models/site_customization/page.rb +++ b/app/models/site_customization/page.rb @@ -7,6 +7,7 @@ class SiteCustomization::Page < ActiveRecord::Base validates :status, presence: true, inclusion: { in: VALID_STATUSES } scope :published, -> { where(status: 'published').order('id DESC') } + scope :with_more_info_flag, -> { where(status: 'published', more_info_flag: true).order('id ASC') } def url "/#{slug}" diff --git a/app/views/admin/site_customization/pages/index.html.erb b/app/views/admin/site_customization/pages/index.html.erb index 356a1813b..eef3370e6 100644 --- a/app/views/admin/site_customization/pages/index.html.erb +++ b/app/views/admin/site_customization/pages/index.html.erb @@ -2,19 +2,12 @@ Admin - <%= t("admin.menu.site_customization.pages") %> <% end %> -
    -
    -
    -

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

    -
    -
    - <%= link_to t("admin.site_customization.pages.index.create"), new_admin_site_customization_page_path, class: "button" %> -
    -
    +<%= link_to t("admin.site_customization.pages.index.create"), new_admin_site_customization_page_path, class: "button float-right margin-right" %> +

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

    <%= page_entries_info @pages %>

    - +
    @@ -33,7 +26,7 @@ - +
    <%= t("admin.site_customization.pages.page.title") %> <%= I18n.l page.created_at, format: :short %> <%= I18n.l page.created_at, format: :short %><%= t("admin.legislation.processes.process.status_#{page.status}") %><%= t("admin.site_customization.pages.page.status_#{page.status}") %> <%= link_to t("admin.site_customization.pages.index.see_page"), page.url %> @@ -48,5 +41,3 @@
    <%= paginate @pages %> - -
    diff --git a/app/views/pages/custom_page.html.erb b/app/views/pages/custom_page.html.erb new file mode 100644 index 000000000..f14eba7d9 --- /dev/null +++ b/app/views/pages/custom_page.html.erb @@ -0,0 +1,15 @@ +<% provide :title do %><%= @custom_page.title %><% end %> + +
    + +
    +

    <%= @custom_page.title %>

    +

    <%= @custom_page.subtitle %>

    + + <%= raw @custom_page.content %> +
    + +
    + <%= render '/shared/print' if @custom_page.print_content_flag %> +
    +
    diff --git a/app/views/pages/more_info/_other.html.erb b/app/views/pages/more_info/_other.html.erb index d0718294c..5501c9e31 100644 --- a/app/views/pages/more_info/_other.html.erb +++ b/app/views/pages/more_info/_other.html.erb @@ -4,4 +4,8 @@
  • <%= link_to t("pages.more_info.other.how_to_use", org_name: setting['org_name']), faq_path %>
  • <%= link_to t("pages.more_info.other.facts"), participation_facts_path %>
  • <%= link_to t("pages.more_info.other.world"), participation_world_path %>
  • + + <% SiteCustomization::Page.with_more_info_flag.each do |custom_page| %> +
  • <%= link_to custom_page.title, page_path(custom_page.slug) %>
  • + <% end %> diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index f95f0a550..85844f948 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -152,6 +152,7 @@ ignore_unused: - 'views.pagination.*' # kaminari - 'shared.suggest.*' - 'invisible_captcha.*' + - 'admin.site_customization.pages.page.status_*' # - '{devise,kaminari,will_paginate}.*' # - 'simple_form.{yes,no}' # - 'simple_form.{placeholders,hints,labels}.*' diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index d44179ce8..be2f9280e 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -508,3 +508,5 @@ en: status: Status title: Title updated_at: Updated at + status_draft: Draft + status_published: Published diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index f93433546..7b14bf90a 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -508,3 +508,5 @@ es: status: Estado title: Título updated_at: Última actualización + status_draft: Borrador + status_published: Publicada diff --git a/config/routes.rb b/config/routes.rb index e31bd86a0..af9ac8a08 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -224,7 +224,7 @@ Rails.application.routes.draw do resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy] namespace :site_customization do - resources :pages + resources :pages, except: [:show] end end diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb index b9ebeb273..20b817f50 100644 --- a/spec/features/admin/site_customization/pages_spec.rb +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -1,50 +1,48 @@ require 'rails_helper' -feature 'Admin custom pages' do +feature "Admin custom pages" do background do admin = create(:administrator) login_as(admin.user) end - context "Index" do - scenario 'Displaying custom pages' do - custom_page = create(:site_customization_page) - visit admin_site_customization_pages_path + scenario "Index" do + custom_page = create(:site_customization_page) + visit admin_site_customization_pages_path - expect(page).to have_content(custom_page.title) - end + expect(page).to have_content(custom_page.title) end - context 'Create' do - scenario 'Valid custom page' do + context "Create" do + scenario "Valid custom page" do visit admin_root_path - within('#side_menu') do + within("#side_menu") do click_link "Custom Pages" end - expect(page).to_not have_content 'An example custom page' + expect(page).to_not have_content "An example custom page" click_link "Create new page" - fill_in 'site_customization_page_title', with: 'An example custom page' - fill_in 'site_customization_page_subtitle', with: 'Page subtitle' - fill_in 'site_customization_page_slug', with: 'example-page' - fill_in 'site_customization_page_content', with: 'This page is about...' + fill_in "site_customization_page_title", with: "An example custom page" + fill_in "site_customization_page_subtitle", with: "Page subtitle" + fill_in "site_customization_page_slug", with: "example-page" + fill_in "site_customization_page_content", with: "This page is about..." - click_button 'Create Custom page' + click_button "Create Custom page" - expect(page).to have_content 'An example custom page' + expect(page).to have_content "An example custom page" end end - context 'Update' do - scenario 'Valid custom page' do - custom_page = create(:site_customization_page, title: 'An example custom page') + context "Update" do + scenario "Valid custom page" do + custom_page = create(:site_customization_page, title: "An example custom page") visit admin_root_path - within('#side_menu') do + within("#side_menu") do click_link "Custom Pages" end @@ -52,11 +50,20 @@ feature 'Admin custom pages' do expect(page).to have_selector("h2", text: "An example custom page") - fill_in 'site_customization_page_title', with: 'Another example custom page' + fill_in "site_customization_page_title", with: "Another example custom page" click_button "Update Custom page" expect(page).to have_content "Page updated successfully" - expect(page).to have_content 'Another example custom page' + expect(page).to have_content "Another example custom page" end end + + scenario "Index" do + custom_page = create(:site_customization_page, title: "An example custom page") + visit edit_admin_site_customization_page_path(custom_page) + + click_button "Delete" + + expect(page).to_not have_content("An example custom page") + end end diff --git a/spec/features/site_customization/custom_pages_spec.rb b/spec/features/site_customization/custom_pages_spec.rb new file mode 100644 index 000000000..2e2fac84a --- /dev/null +++ b/spec/features/site_customization/custom_pages_spec.rb @@ -0,0 +1,102 @@ +require 'rails_helper' + +feature "Custom Pages" do + context "Override existing page" do + scenario "See default content when custom page is not published" do + custom_page = create(:site_customization_page, + slug: "conditions", + title: "Custom conditions", + content: "New text for conditions page", + print_content_flag: true + ) + + visit custom_page.url + + expect(page).to have_title("Terms of use") + expect(page).to have_selector("h1", text: "Terms and conditions of use") + expect(page).to have_content("Página de información sobre las condiciones de uso, privacidad y protección de datos personales.") + expect(page).to have_content("Print this info") + end + + scenario "See custom content when custom page is published" do + custom_page = create(:site_customization_page, :published, + slug: "conditions", + title: "Custom conditions", + content: "New text for conditions page", + print_content_flag: true + ) + + visit custom_page.url + + expect(page).to have_title("Custom conditions") + expect(page).to have_selector("h1", text: "Custom conditions") + expect(page).to have_content("New text for conditions page") + expect(page).to have_content("Print this info") + end + end + + context "New custom page" do + context "Draft" do + scenario "See page" do + custom_page = create(:site_customization_page, + slug: "other-slug", + title: "Custom page", + content: "Text for new custom page", + print_content_flag: false + ) + + visit custom_page.url + + expect(page.status_code).to eq(404) + end + end + + context "Published" do + scenario "See page" do + custom_page = create(:site_customization_page, :published, + slug: "other-slug", + title: "Custom page", + content: "Text for new custom page", + print_content_flag: false + ) + + visit custom_page.url + + expect(page).to have_title("Custom page") + expect(page).to have_selector("h1", text: "Custom page") + expect(page).to have_content("Text for new custom page") + expect(page).to_not have_content("Print this info") + end + + scenario "Listed in more information page" do + custom_page = create(:site_customization_page, :published, + slug: "another-slug", title: "Another custom page", + subtitle: "Subtitle for custom page", + more_info_flag: true + ) + + visit more_info_path + + expect(page).to have_content("Another custom page") + end + + scenario "Not listed in more information page" do + custom_page = create(:site_customization_page, :published, + slug: "another-slug", title: "Another custom page", + subtitle: "Subtitle for custom page", + more_info_flag: false + ) + + visit more_info_path + + expect(page).to_not have_content("Another custom page") + + visit custom_page.url + + expect(page).to have_title("Another custom page") + expect(page).to have_selector("h1", text: "Another custom page") + expect(page).to have_content("Subtitle for custom page") + end + end + end +end From 8143fe10370edb1eb2edd5ca31ff34576d157097 Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Thu, 23 Mar 2017 18:03:22 +0100 Subject: [PATCH 532/613] Site customization: images uploads --- Gemfile | 2 + Gemfile.lock | 10 ++- .../site_customization/images_controller.rb | 43 ++++++++++++ .../site_customization/pages_controller.rb | 4 +- app/helpers/application_helper.rb | 4 ++ app/models/abilities/administrator.rb | 1 + app/models/site_customization/image.rb | 48 ++++++++++++++ app/views/admin/_menu.html.erb | 6 ++ .../site_customization/images/index.html.erb | 25 +++++++ app/views/layouts/_admin_header.html.erb | 4 +- app/views/layouts/_header.html.erb | 2 +- app/views/layouts/application.html.erb | 2 +- app/views/layouts/devise.html.erb | 2 +- app/views/layouts/management.html.erb | 2 +- .../shared/_social_media_meta_tags.html.erb | 4 +- app/views/welcome/index.html.erb | 2 +- config/locales/activerecord.en.yml | 8 +++ config/locales/activerecord.es.yml | 8 +++ config/locales/admin.en.yml | 16 ++++- config/locales/admin.es.yml | 18 ++++- config/routes.rb | 1 + ...145702_create_site_customization_images.rb | 11 ++++ db/schema.rb | 14 +++- .../admin/site_customization/images_spec.rb | 62 ++++++++++++++++++ .../admin/site_customization/pages_spec.rb | 4 +- spec/fixtures/files/logo_header.png | Bin 0 -> 463 bytes spec/fixtures/files/social-media-icon.png | Bin 0 -> 3353 bytes 27 files changed, 283 insertions(+), 20 deletions(-) create mode 100644 app/controllers/admin/site_customization/images_controller.rb create mode 100644 app/models/site_customization/image.rb create mode 100644 app/views/admin/site_customization/images/index.html.erb create mode 100644 db/migrate/20170322145702_create_site_customization_images.rb create mode 100644 spec/features/admin/site_customization/images_spec.rb create mode 100644 spec/fixtures/files/logo_header.png create mode 100644 spec/fixtures/files/social-media-icon.png diff --git a/Gemfile b/Gemfile index f9c2f54e5..39dee65f8 100644 --- a/Gemfile +++ b/Gemfile @@ -65,6 +65,8 @@ gem 'browser' gem 'turnout', '~> 2.4.0' gem 'redcarpet', '~> 3.4.0' +gem 'paperclip' + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 6c117ea77..67ab5a78b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -238,6 +238,7 @@ GEM mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) + mimemagic (0.3.2) mini_portile2 (2.1.0) minitest (5.10.1) multi_json (1.12.1) @@ -277,6 +278,12 @@ GEM omniauth-oauth (~> 1.1) rack orm_adapter (0.5.0) + paperclip (5.1.0) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + cocaine (~> 0.5.5) + mime-types + mimemagic (~> 0.3.0) paranoia (2.2.1) activerecord (>= 4.0, < 5.1) parser (2.4.0.0) @@ -504,6 +511,7 @@ DEPENDENCIES omniauth-facebook (~> 4.0.0) omniauth-google-oauth2 (~> 0.4.0) omniauth-twitter + paperclip paranoia (~> 2.2.1) pg (~> 0.20.0) pg_search @@ -533,4 +541,4 @@ DEPENDENCIES whenever BUNDLED WITH - 1.13.7 + 1.14.6 diff --git a/app/controllers/admin/site_customization/images_controller.rb b/app/controllers/admin/site_customization/images_controller.rb new file mode 100644 index 000000000..c9f318f41 --- /dev/null +++ b/app/controllers/admin/site_customization/images_controller.rb @@ -0,0 +1,43 @@ +class Admin::SiteCustomization::ImagesController < Admin::SiteCustomization::BaseController + load_and_authorize_resource :image, class: "SiteCustomization::Image" + + def index + @images = SiteCustomization::Image.all_images + end + + def update + if params[:site_customization_image].nil? + redirect_to admin_site_customization_images_path + return + end + + if @image.update(image_params) + redirect_to admin_site_customization_images_path, notice: t('admin.site_customization.images.update.notice') + else + flash.now[:error] = t('admin.site_customization.images.update.error') + + @images = SiteCustomization::Image.all_images + idx = @images.index {|e| e.name == @image.name } + @images[idx] = @image + + render :index + end + end + + def destroy + @image.image = nil + if @image.save + redirect_to admin_site_customization_images_path, notice: t('admin.site_customization.images.destroy.notice') + else + redirect_to admin_site_customization_images_path, notice: t('admin.site_customization.images.destroy.error') + end + end + + private + + def image_params + params.require(:site_customization_image).permit( + :image + ) + end +end diff --git a/app/controllers/admin/site_customization/pages_controller.rb b/app/controllers/admin/site_customization/pages_controller.rb index 0b838054e..4d92a6a1e 100644 --- a/app/controllers/admin/site_customization/pages_controller.rb +++ b/app/controllers/admin/site_customization/pages_controller.rb @@ -7,7 +7,7 @@ class Admin::SiteCustomization::PagesController < Admin::SiteCustomization::Base def create if @page.save - redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.create.notice', link: @page.slug.html_safe) + redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.create.notice') else flash.now[:error] = t('admin.site_customization.pages.create.error') render :new @@ -16,7 +16,7 @@ class Admin::SiteCustomization::PagesController < Admin::SiteCustomization::Base def update if @page.update(page_params) - redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.update.notice', link: @page.slug.html_safe) + redirect_to admin_site_customization_pages_path, notice: t('admin.site_customization.pages.update.notice') else flash.now[:error] = t('admin.site_customization.pages.update.error') render :edit diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 208ed3d3d..c449fa9f4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -47,4 +47,8 @@ module ApplicationHelper "".html_safe + t("shared.back") end end + + def image_path_for(filename) + SiteCustomization::Image.image_path_for(filename) || filename + end end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index 8df9270a3..c61530772 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -53,6 +53,7 @@ module Abilities can [:index, :create, :edit, :update, :destroy], Geozone can :manage, SiteCustomization::Page + can :manage, SiteCustomization::Image end end end diff --git a/app/models/site_customization/image.rb b/app/models/site_customization/image.rb new file mode 100644 index 000000000..2230a96ce --- /dev/null +++ b/app/models/site_customization/image.rb @@ -0,0 +1,48 @@ +class SiteCustomization::Image < ActiveRecord::Base + VALID_IMAGES = { + "icon_home" => [330, 240], + "logo_header" => [80, 80], + "social-media-icon" => [200, 200], + "apple-touch-icon-200" => [200, 200] + } + + has_attached_file :image + + validates :name, presence: true, uniqueness: true, inclusion: { in: VALID_IMAGES.keys } + validates_attachment_content_type :image, :content_type => ["image/png"] + validate :check_image + + def self.all_images + VALID_IMAGES.keys.map do |image_name| + find_by(name: image_name) || create!(name: image_name.to_s) + end + end + + def self.image_path_for(filename) + image_name = filename.split(".").first + + if i = find_by(name: image_name) + i.image.exists? ? i.image.url : nil + end + end + + def required_width + VALID_IMAGES[name].try(:first) + end + + def required_height + VALID_IMAGES[name].try(:second) + end + + private + + def check_image + return unless image? + + dimensions = Paperclip::Geometry.from_file(image.queued_for_write[:original].path) + + errors.add(:image, :image_width, required_width: required_width) unless dimensions.width == required_width + errors.add(:image, :image_height, required_height: required_height) unless dimensions.height == required_height + end + +end diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 448da1662..6a48b493b 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -128,5 +128,11 @@ <%= t("admin.menu.site_customization.pages") %> <% end %> + +
  • > + <%= link_to admin_site_customization_images_path do %> + <%= t("admin.menu.site_customization.images") %> + <% end %> +
  • diff --git a/app/views/admin/site_customization/images/index.html.erb b/app/views/admin/site_customization/images/index.html.erb new file mode 100644 index 000000000..b9de152d1 --- /dev/null +++ b/app/views/admin/site_customization/images/index.html.erb @@ -0,0 +1,25 @@ +

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

    + + + + <% @images.each do |image| %> + + + + + <% end %> + +
    + <%= image.name %> (<%= image.required_width %>x<%= image.required_height %>) + + <%= form_for([:admin, image], html: { id: "edit_#{dom_id(image)}"}) do |f| %> +
    + <%= image_tag image.image.url if image.image.exists? %> + <%= f.file_field :image, label: false %> +
    +
    + <%= f.submit(t('admin.site_customization.images.index.update'), class: "button hollow") %> + <%= link_to t('admin.site_customization.images.index.delete'), admin_site_customization_image_path(image), method: :delete, class: "button hollow alert" if image.image.exists? %> +
    + <% end %> +
    diff --git a/app/views/layouts/_admin_header.html.erb b/app/views/layouts/_admin_header.html.erb index 095e351d6..72617386c 100644 --- a/app/views/layouts/_admin_header.html.erb +++ b/app/views/layouts/_admin_header.html.erb @@ -18,7 +18,7 @@
    <%= 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")) %> + <%= image_tag(image_path_for('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 %> @@ -34,4 +34,4 @@
    - \ No newline at end of file + diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb index 9a33662c6..a3162bb8c 100644 --- a/app/views/layouts/_header.html.erb +++ b/app/views/layouts/_header.html.erb @@ -22,7 +22,7 @@
    <%= link_to root_path, class: "hide-for-small-only", accesskey: "0" do %> - <%= image_tag('logo_header.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> + <%= image_tag(image_path_for('logo_header.png'), class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> <%= setting['org_name'] %> <% end %>
    diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ef4455320..7ae505aad 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -14,7 +14,7 @@ <%= javascript_include_tag "application", 'data-turbolinks-track' => true %> <%= csrf_meta_tags %> <%= favicon_link_tag "favicon.ico" %> - <%= favicon_link_tag "apple-touch-icon-200.png", + <%= favicon_link_tag image_path_for("apple-touch-icon-200.png"), rel: "icon apple-touch-icon", sizes: "200x200", type: "image/png" %> diff --git a/app/views/layouts/devise.html.erb b/app/views/layouts/devise.html.erb index a0e9eaaff..50b84287d 100644 --- a/app/views/layouts/devise.html.erb +++ b/app/views/layouts/devise.html.erb @@ -17,7 +17,7 @@

    <%= link_to root_path do %> - <%= image_tag('logo_header.png', class: 'float-left', alt: t("layouts.header.logo")) %> + <%= image_tag(image_path_for('logo_header.png'), class: 'float-left', alt: t("layouts.header.logo")) %> <%= setting['org_name'] %> <% end %>

    diff --git a/app/views/layouts/management.html.erb b/app/views/layouts/management.html.erb index 8e497bf24..21367d8ab 100644 --- a/app/views/layouts/management.html.erb +++ b/app/views/layouts/management.html.erb @@ -35,7 +35,7 @@
    <%= link_to management_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")) %> + <%= image_tag(image_path_for('logo_header.png'), class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %> <%= setting['org_name'] %>  | <%= t("management.dashboard.index.title") %> <% end %> diff --git a/app/views/shared/_social_media_meta_tags.html.erb b/app/views/shared/_social_media_meta_tags.html.erb index 50a2efec9..c0e6a5e8a 100644 --- a/app/views/shared/_social_media_meta_tags.html.erb +++ b/app/views/shared/_social_media_meta_tags.html.erb @@ -3,7 +3,7 @@ - + <% if setting['url'] %> @@ -14,7 +14,7 @@ <% end %> - + diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 32124a950..1eb6cf38c 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -12,7 +12,7 @@
    - <%= image_tag("icon_home.png", size: "330x240", alt:"") %> + <%= image_tag(image_path_for("icon_home.png"), size: "330x240", alt:"") %>
    diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index e8354b88e..bd18422ae 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -43,6 +43,9 @@ en: site_customization/page: one: Custom page other: Custom pages + site_customization/image: + one: Custom image + other: Custom images attributes: budget: name: "Name" @@ -151,3 +154,8 @@ en: attributes: slug: slug_format: "must be letters, numbers, _ and -" + site_customization/image: + attributes: + image: + image_width: "Width must be %{required_width}px" + image_height: "Height must be %{required_height}px" diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index 32b26223b..f3397ef19 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -43,6 +43,9 @@ es: site_customization/page: one: Página other: Páginas + site_customization/image: + one: Imagen + other: Imágenes attributes: budget: name: "Nombre" @@ -146,3 +149,8 @@ es: attributes: slug: slug_format: "deber ser letras, números, _ y -" + site_customization/image: + attributes: + image: + image_width: "Debe tener %{required_width}px de ancho" + image_height: "Debe tener %{required_height}px de alto" diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index be2f9280e..5f84f69d3 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -209,6 +209,7 @@ en: signature_sheets: Signature Sheets site_customization: pages: Custom Pages + images: Custom Images moderators: index: title: Moderators @@ -478,12 +479,23 @@ en: sms_code_not_confirmed: Has not confirmed the sms code title: Incomplete verifications site_customization: + images: + index: + title: Custom images + update: Update + delete: Delete + update: + notice: Image updated successfully + error: Image couldn't be updated + destroy: + notice: Image deleted successfully + error: Image couldn't be deleted pages: create: - notice: 'Page created successfully.' + notice: Page created successfully error: Process couldn't be created update: - notice: 'Page updated successfully.' + notice: Page updated successfully error: Page couldn't be updated destroy: notice: Page deleted successfully diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 7b14bf90a..f4c834e34 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -208,7 +208,8 @@ es: stats: Estadísticas signature_sheets: Hojas de firmas site_customization: - pages: Páginas + pages: Personalizar páginas + images: Personalizar imágenes moderators: index: title: Moderadores @@ -478,12 +479,23 @@ es: sms_code_not_confirmed: No ha introducido su código de seguridad title: Verificaciones incompletas site_customization: + images: + index: + title: Personalizar imágenes + update: Actualizar + delete: Borrar + update: + notice: Imagen actualizada correctamente + error: No se ha podido actualizar la imagen + destroy: + notice: Imagen borrada correctamente + error: No se ha podido borrar la imagen pages: create: - notice: 'Página creada correctamente.' + notice: Página creada correctamente error: No se ha podido crear la página update: - notice: 'Página actualizada correctamente.s' + notice: Página actualizada correctamente error: No se ha podido actualizar la página destroy: notice: Página eliminada correctamente diff --git a/config/routes.rb b/config/routes.rb index af9ac8a08..51d2a47da 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -225,6 +225,7 @@ Rails.application.routes.draw do namespace :site_customization do resources :pages, except: [:show] + resources :images, only: [:index, :update, :destroy] end end diff --git a/db/migrate/20170322145702_create_site_customization_images.rb b/db/migrate/20170322145702_create_site_customization_images.rb new file mode 100644 index 000000000..4f980b566 --- /dev/null +++ b/db/migrate/20170322145702_create_site_customization_images.rb @@ -0,0 +1,11 @@ +class CreateSiteCustomizationImages < ActiveRecord::Migration + def change + create_table :site_customization_images do |t| + t.string :name, null: false + t.attachment :image + t.timestamps null: false + end + + add_index :site_customization_images, :name, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 0b38a4196..938fbb9ec 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: 20170316174351) do +ActiveRecord::Schema.define(version: 20170322145702) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -439,6 +439,18 @@ ActiveRecord::Schema.define(version: 20170316174351) do t.datetime "updated_at" end + create_table "site_customization_images", force: :cascade do |t| + t.string "name", null: false + t.string "image_file_name" + t.string "image_content_type" + t.integer "image_file_size" + t.datetime "image_updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "site_customization_images", ["name"], name: "index_site_customization_images_on_name", unique: true, using: :btree + create_table "site_customization_pages", force: :cascade do |t| t.string "slug", null: false t.string "title", null: false diff --git a/spec/features/admin/site_customization/images_spec.rb b/spec/features/admin/site_customization/images_spec.rb new file mode 100644 index 000000000..094ac19bf --- /dev/null +++ b/spec/features/admin/site_customization/images_spec.rb @@ -0,0 +1,62 @@ +require 'rails_helper' + +feature "Admin custom images" do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Upload valid image" do + visit admin_root_path + + within("#side_menu") do + click_link "Custom Images" + end + + within("tr.logo_header") do + attach_file "site_customization_image_image", "spec/fixtures/files/logo_header.png" + click_button "Update" + end + + expect(page).to have_css("tr.logo_header img[src*='logo_header.png']") + expect(page).to have_css("img[src*='logo_header.png']", count: 2) # one in the admin form an one in the page header + end + + scenario "Upload invalid image" do + visit admin_root_path + + within("#side_menu") do + click_link "Custom Images" + end + + within("tr.icon_home") do + attach_file "site_customization_image_image", "spec/fixtures/files/logo_header.png" + click_button "Update" + end + + expect(page).to have_content("Width must be 330px") + expect(page).to have_content("Height must be 240px") + end + + scenario "Delete image" do + visit admin_root_path + + within("#side_menu") do + click_link "Custom Images" + end + + within("tr.social-media-icon") do + attach_file "site_customization_image_image", "spec/fixtures/files/social-media-icon.png" + click_button "Update" + end + + expect(page).to have_css("img[src*='social-media-icon.png']") + + within("tr.social-media-icon") do + click_link "Delete" + end + + expect(page).to_not have_css("img[src*='social-media-icon.png']") + end +end diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb index 20b817f50..5d03638d8 100644 --- a/spec/features/admin/site_customization/pages_spec.rb +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -39,7 +39,7 @@ feature "Admin custom pages" do context "Update" do scenario "Valid custom page" do - custom_page = create(:site_customization_page, title: "An example custom page") + create(:site_customization_page, title: "An example custom page") visit admin_root_path within("#side_menu") do @@ -58,7 +58,7 @@ feature "Admin custom pages" do end end - scenario "Index" do + scenario "Delete" do custom_page = create(:site_customization_page, title: "An example custom page") visit edit_admin_site_customization_page_path(custom_page) diff --git a/spec/fixtures/files/logo_header.png b/spec/fixtures/files/logo_header.png new file mode 100644 index 0000000000000000000000000000000000000000..5f53555744121150dfe598df06fe86f37079d3d7 GIT binary patch literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^0U*r51|<6gKdl8)Y)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPtvzP#z^keqBd<+bXF`h1tAr-gY-nlKyo5Xf?>f2fHB@6Y;-h8rto}ik%bkW2_PtCh0zDlq#FmWg}usARzr=6AEkbnG& z@X^18@hcp56+F<32|jnY$9Qr@bbm^<^id?ru2F59`e}y~bP0l+XkKoT#qZ literal 0 HcmV?d00001 diff --git a/spec/fixtures/files/social-media-icon.png b/spec/fixtures/files/social-media-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fcd00e212f4902b2cf737405a3b55024703ecfcf GIT binary patch literal 3353 zcmZ{n2T&7Ax5tyvq)A7*6zRPPD1@K{LlL;NP^EW}jzB`ol`36&Nsta2iYUZL3m_mD z5T%G9hF}l{6@-MMpuF5~=6&t?&d%ALIsZAkb7r>uHtP>d7(0s)3jhFMH#LFU(8lL~ z`x!=B-{#nkp$&{)<}fJW^zU}BzqyDOVGcKOiUI&wdH!}Fpt4$k7G#PxwJ>H{qvPii z<3P|Kivj>_O{UN*c5%yJ(ZM;@_M#azfw4GWdA^);AY~VrB|)#aOKOXJ(XNHH zFIkc(f@1mf9n4|RSp+VylP5h zE2Ckfvq%+^s<<&0b9_VWK%8uh`UQ#C`TTe2N^u%UP;<*WuI5L1*{EYTW<-uu+he0% zA_v&_QLt87cnuUz3G@K!F8S6!;?`xEvb#U(Q1&!T?;-sDC?b2+ogTZRv5|Fz?q}|^ zYvs>>>;jh}mixj7WkSR)6{)#|*pwK8Qg~l>a61T2*8xffif!#?yKI4lQEz)Q@c=Av z10{<>qRL=x>W`QNxs2RY7PJ8nh9tJ@zTv%>NMfXRvu@qF2d`Ahg3{y$>6I-V3*B$TjXUYlVC1mE#_zz0tf*OoLMO^)XiMPs}sHT zI@@fN#oUxiwGmCZ1bU5KM!Q<8>XhOe(!I=d1qsY3$IDxo_rs8n*)KEd<@35d7q)%EHO6<+*9%2iJdudxzIpUI(+<1w17}ztpM#4$92C``O7D?F3;mRwprU z|5a4=r$@R%>Q-Z72UqVg>UTja6bgKOUaaQw-Sh(BV`dMp%j6uN_3)3xG^7z!?`$M^ zYpp+E{KIXcT-M8}zY6vUBU|Ja_G2Y#*BpY&A82_w{Nxe)19;!YSJrWkRYu+L_x$wsf1|pYaCYtBGAG z$o22v#C%3^aBT=fQEVk8sXyPdIbAT7GB9@}Hyr*UZuC*kGlJx5>#NLWD#DqL_*ll7 zDdmDFK&ct&2CnlBcTs|E5QRw&V;jfV+aMc6m8jtQ^4(A1^i(ON@kL-Gzi6pp6%bwogZj>X zk**e>4QeI{6AlDceN+3XX)-{0euleFL319$YYl~ujf5GkcikkFL|27u2fedT-u0*Q zSP!r!Bxc@bW$_VgvTs(f*%O$F>w4aPwA@WAt%&ZrJCPoPwacElfatwiG}tmeBIG7t z7Q~d2Z@l_=NGn)vJpzx^R0Sl1w*7W<4P&|>DG2$nLj8qx`c8%;x46`3f0(#VdO$O$$euerR`tB+VXRkrJJng)5vAJ#%4=~%h zYe2n0+Rb*n2fq}lS}~T{tgQx2#Z%i^rX*=ngwHJLjV)3bHvNw%#v7(ANaKew= z7VAFBQU55EMH#&lAOgo$HX{=(5P59hWrn?Hx5azMyQFQq0*85mnvo_;j9i+1gHyjO zNfFMf<2a^?LW$MlyLD9BLK}x)=*~)a3>L46UY%kmf_|0sh$Q1VzHVF^6-t$`G7mn> zrF{*|pg&!auPHEEJ`)JMp3_mBQ1d~jx8=z?J%M^af^e%OQ|wKu_>|6k((!C_=^aiSRYtT(s}q&YYi$i6YSQEYPJA zmLBK&Cc{#l@p>nWq=;Ce^4ccODf)Cm@RPjdYAiAP8ysr&QYp`}tiPerD}%YYFNCf~ z>wAN1*wXZ8{pSzOx}TJE&X74?LH)mOZg~5;RoT?`u3hllYsc^LBQhUeA(QSPZS-O7 z97)gL>YGr0ZIdHv#uJ1$Vp>H83OL75qM zH?svIXXb_%`Z!CI^#OfsuIJg0x3s5k-t}j0&I!p6G0FC;V zuMQh4kWg0 zgl(Z;yqPbK=)lcq?X-C%nHjYkBG%%x-cV9~*KwQ&F^eg%`nVTakl2PSDLNx!d!Q9& zu2*^>iD!+zw3S~S(k9^`-cMC{L>QcGTux@rrnZAr7=F>67>I>}MO{9SMJu->Zf0~bhwjJw%?j>MW$b&J-ZIvFNU7d9|bo$_YJ-~6ry6aw*Zf}q{7*)uQSona_aDK3u<~#8|6u9=)kVn^X5Wyl7iySDm;CedvYlql z?_2VFCEKW7ScDMxHxv#nRRmkL(4K>_n5};yy}Fqfk6`!H@&#w5vhwG0o{79%zqbkb bQzobvL?qkdav$vz128qVgtlMx`15}Nuhbo& literal 0 HcmV?d00001 From ae3690ab5f43e7b9832e8d5fd08b4054e4883bdd Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Wed, 5 Apr 2017 13:26:57 +0200 Subject: [PATCH 533/613] Validate presence of page slug --- app/models/site_customization/page.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/models/site_customization/page.rb b/app/models/site_customization/page.rb index ea3003465..c2a9b1467 100644 --- a/app/models/site_customization/page.rb +++ b/app/models/site_customization/page.rb @@ -1,8 +1,9 @@ class SiteCustomization::Page < ActiveRecord::Base VALID_STATUSES = %w(draft published) - validates :slug, uniqueness: { case_sensitive: false }, - format: { with: /\A[0-9a-zA-Z\-_]*\Z/, message: :slug_format } + validates :slug, presence: true, + uniqueness: { case_sensitive: false }, + format: { with: /\A[0-9a-zA-Z\-_]*\Z/, message: :slug_format } validates :title, presence: true validates :status, presence: true, inclusion: { in: VALID_STATUSES } From c1de2dced4c26447002badc1b955747b67a07afd Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Fri, 24 Mar 2017 17:12:33 +0100 Subject: [PATCH 534/613] Custom content blocks for top_links and footer --- .gitignore | 3 +- .../content_blocks_controller.rb | 40 +++++++ app/helpers/application_helper.rb | 4 + app/models/abilities/administrator.rb | 1 + .../site_customization/content_block.rb | 11 ++ app/views/admin/_menu.html.erb | 6 + .../content_blocks/_form.html.erb | 34 ++++++ .../content_blocks/edit.html.erb | 15 +++ .../content_blocks/index.html.erb | 29 +++++ .../content_blocks/new.html.erb | 14 +++ app/views/layouts/_footer.html.erb | 6 +- app/views/shared/_top_links.html.erb | 14 ++- config/locales/activerecord.en.yml | 10 ++ config/locales/activerecord.es.yml | 10 ++ config/locales/admin.en.yml | 28 ++++- config/locales/admin.es.yml | 26 +++++ config/routes.rb | 1 + ...reate_site_customization_content_blocks.rb | 13 +++ db/schema.rb | 12 +- db/seeds.rb | 2 + spec/factories.rb | 6 + .../site_customization/content_blocks_spec.rb | 107 ++++++++++++++++++ .../site_customization/content_blocks_spec.rb | 33 ++++++ .../site_customization/content_block_spec.rb | 20 ++++ 24 files changed, 435 insertions(+), 10 deletions(-) create mode 100644 app/controllers/admin/site_customization/content_blocks_controller.rb create mode 100644 app/models/site_customization/content_block.rb create mode 100644 app/views/admin/site_customization/content_blocks/_form.html.erb create mode 100644 app/views/admin/site_customization/content_blocks/edit.html.erb create mode 100644 app/views/admin/site_customization/content_blocks/index.html.erb create mode 100644 app/views/admin/site_customization/content_blocks/new.html.erb create mode 100644 db/migrate/20170324101716_create_site_customization_content_blocks.rb create mode 100644 spec/features/admin/site_customization/content_blocks_spec.rb create mode 100644 spec/features/site_customization/content_blocks_spec.rb create mode 100644 spec/models/site_customization/content_block_spec.rb diff --git a/.gitignore b/.gitignore index 35f5651a4..a6f2826c3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,5 @@ .DS_Store .ruby-gemset -public/sitemap.xml \ No newline at end of file +public/sitemap.xml +public/system/ diff --git a/app/controllers/admin/site_customization/content_blocks_controller.rb b/app/controllers/admin/site_customization/content_blocks_controller.rb new file mode 100644 index 000000000..2f0843ccc --- /dev/null +++ b/app/controllers/admin/site_customization/content_blocks_controller.rb @@ -0,0 +1,40 @@ +class Admin::SiteCustomization::ContentBlocksController < Admin::SiteCustomization::BaseController + load_and_authorize_resource :content_block, class: "SiteCustomization::ContentBlock" + + def index + @content_blocks = SiteCustomization::ContentBlock.order(:name, :locale) + end + + def create + if @content_block.save + redirect_to admin_site_customization_content_blocks_path, notice: t('admin.site_customization.content_blocks.create.notice') + else + flash.now[:error] = t('admin.site_customization.content_blocks.create.error') + render :new + end + end + + def update + if @content_block.update(content_block_params) + redirect_to admin_site_customization_content_blocks_path, notice: t('admin.site_customization.content_blocks.update.notice') + else + flash.now[:error] = t('admin.site_customization.content_blocks.update.error') + render :edit + end + end + + def destroy + @content_block.destroy + redirect_to admin_site_customization_content_blocks_path, notice: t('admin.site_customization.content_blocks.destroy.notice') + end + + private + + def content_block_params + params.require(:site_customization_content_block).permit( + :name, + :locale, + :body + ) + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index c449fa9f4..0c23c0d22 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -51,4 +51,8 @@ module ApplicationHelper def image_path_for(filename) SiteCustomization::Image.image_path_for(filename) || filename end + + def content_block(name, locale) + SiteCustomization::ContentBlock.block_for(name, locale) + end end diff --git a/app/models/abilities/administrator.rb b/app/models/abilities/administrator.rb index c61530772..a99b98fea 100644 --- a/app/models/abilities/administrator.rb +++ b/app/models/abilities/administrator.rb @@ -54,6 +54,7 @@ module Abilities can :manage, SiteCustomization::Page can :manage, SiteCustomization::Image + can :manage, SiteCustomization::ContentBlock end end end diff --git a/app/models/site_customization/content_block.rb b/app/models/site_customization/content_block.rb new file mode 100644 index 000000000..c08beb52e --- /dev/null +++ b/app/models/site_customization/content_block.rb @@ -0,0 +1,11 @@ +class SiteCustomization::ContentBlock < ActiveRecord::Base + VALID_BLOCKS = %w(top_links footer) + + validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) } + validates :name, presence: true, uniqueness: { scope: :locale }, inclusion: { in: VALID_BLOCKS } + + def self.block_for(name, locale) + locale ||= I18n.default_locale + find_by(name: name, locale: locale).try(:body) + end +end diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index 6a48b493b..65d8bed79 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -134,5 +134,11 @@ <%= t("admin.menu.site_customization.images") %> <% end %> + +
  • > + <%= link_to admin_site_customization_content_blocks_path do %> + <%= t("admin.menu.site_customization.content_blocks") %> + <% end %> +
  • diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb new file mode 100644 index 000000000..9ca4eb36a --- /dev/null +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -0,0 +1,34 @@ +<%= form_for [:admin, @content_block], html: {class: "edit_page", data: {watch_changes: true}} do |f| %> + + <% if @content_block.errors.any? %> + +
    + + + + <%= @content_block.errors.count %> + <%= t("admin.site_customization.content_blocks.errors.form.error", count: @content_block.errors.count) %> + +
    + + <% end %> + + +
    + <%= f.label :name %> + <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS, label: false %> +
    +
    + <%= f.label :locale %> + <%= f.select :locale, I18n.available_locales, label: false %> +
    + +
    + <%= f.label :body %> + <%= f.text_area :body, label: false, rows: 10 %> + <%= f.submit class: "button success" %> +
    + +<% end %> diff --git a/app/views/admin/site_customization/content_blocks/edit.html.erb b/app/views/admin/site_customization/content_blocks/edit.html.erb new file mode 100644 index 000000000..c96f9a810 --- /dev/null +++ b/app/views/admin/site_customization/content_blocks/edit.html.erb @@ -0,0 +1,15 @@ +<% provide :title do %> + Admin - <%= t("admin.menu.site_customization.content_blocks") %> - <%= @content_block.name %> (<%= @content_block.locale %>) +<% end %> + +<%= link_to admin_site_customization_content_blocks_path, class: "back" do %> + + <%= t("admin.site_customization.content_blocks.edit.back") %> +<% end %> + +<%= button_to t("admin.site_customization.content_blocks.index.delete"), admin_site_customization_content_block_path(@content_block), method: :delete, class: "button hollow alert float-right margin-right" %> + +
    +

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

    + <%= render 'form' %> +
    diff --git a/app/views/admin/site_customization/content_blocks/index.html.erb b/app/views/admin/site_customization/content_blocks/index.html.erb new file mode 100644 index 000000000..653e3e731 --- /dev/null +++ b/app/views/admin/site_customization/content_blocks/index.html.erb @@ -0,0 +1,29 @@ +<% provide :title do %> + Admin - <%= t("admin.menu.site_customization.content_blocks") %> +<% end %> + +<%= link_to t("admin.site_customization.content_blocks.index.create"), new_admin_site_customization_content_block_path, class: "button float-right margin-right" %> +

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

    + + + + + + + + + + + <% @content_blocks.each do |content_block| %> + + + + + + <% end %> + +
    <%= t("admin.site_customization.content_blocks.content_block.name") %><%= t("admin.site_customization.content_blocks.content_block.body") %>
    <%= link_to "#{content_block.name} (#{content_block.locale})", edit_admin_site_customization_content_block_path(content_block) %><%= content_block.body %> + <%= button_to t("admin.site_customization.content_blocks.index.delete"), + admin_site_customization_content_block_path(content_block), + method: :delete, class: "button hollow alert" %> +
    diff --git a/app/views/admin/site_customization/content_blocks/new.html.erb b/app/views/admin/site_customization/content_blocks/new.html.erb new file mode 100644 index 000000000..75ff5f389 --- /dev/null +++ b/app/views/admin/site_customization/content_blocks/new.html.erb @@ -0,0 +1,14 @@ +<% provide :title do %> + Admin - <%= t("admin.menu.site_customization.content_blocks") %> - <%= t("admin.site_customization.content_blocks.new.title") %> +<% end %> + +<%= link_to admin_site_customization_content_blocks_path, class: "back" do %> + + <%= t("admin.site_customization.content_blocks.new.back") %> +<% end %> + +
    +

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

    + <%= render 'form' %> +
    + diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 4b5e90523..1e5c3dfa5 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -1,5 +1,5 @@
    -
    +

    <%= link_to t("layouts.header.open_gov", open: "#{t('layouts.header.open')}").html_safe %> @@ -25,7 +25,7 @@

    - <%= link_to t("layouts.footer.transparency_title"), t("layouts.footer.transparency_url") %> + <%= link_to t("layouts.footer.transparency_title"), setting['transparency_url'].presence || t("layouts.footer.transparency_url") %>

    <%= t("layouts.footer.transparency_text") %>

    @@ -96,4 +96,6 @@

    + + <%= raw content_block("footer", I18n.locale) %>
    diff --git a/app/views/shared/_top_links.html.erb b/app/views/shared/_top_links.html.erb index b97499232..8a71130d6 100644 --- a/app/views/shared/_top_links.html.erb +++ b/app/views/shared/_top_links.html.erb @@ -1,21 +1,25 @@ diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml index bd18422ae..806ddc96f 100644 --- a/config/locales/activerecord.en.yml +++ b/config/locales/activerecord.en.yml @@ -46,6 +46,9 @@ en: site_customization/image: one: Custom image other: Custom images + site_customization/content_block: + one: Custom content block + other: Custom content blocks attributes: budget: name: "Name" @@ -119,6 +122,13 @@ en: updated_at: Updated at more_info_flag: Show in more information page print_content_flag: Print content button + site_customization/image: + name: Name + image: Image + site_customization/content_block: + name: Name + locale: locale + body: Body errors: models: user: diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml index f3397ef19..43c40110e 100644 --- a/config/locales/activerecord.es.yml +++ b/config/locales/activerecord.es.yml @@ -46,6 +46,9 @@ es: site_customization/image: one: Imagen other: Imágenes + site_customization/content_block: + one: Bloque + other: Bloques attributes: budget: name: "Nombre" @@ -114,6 +117,13 @@ es: updated_at: última actualización more_info_flag: Mostrar en la página de más información print_content_flag: Botón de imprimir contenido + site_customization/image: + name: Nombre + image: Imagen + site_customization/content_block: + name: Nombre + locale: Idioma + body: Contenido errors: models: user: diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 5f84f69d3..12911c410 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -210,6 +210,7 @@ en: site_customization: pages: Custom Pages images: Custom Images + content_blocks: Custom content blocks moderators: index: title: Moderators @@ -479,6 +480,31 @@ en: sms_code_not_confirmed: Has not confirmed the sms code title: Incomplete verifications site_customization: + content_blocks: + create: + notice: Content block created successfully + error: Content block couldn't be created + update: + notice: Content block updated successfully + error: Content block couldn't be updated + destroy: + notice: Content block deleted successfully + edit: + title: Editing content block + back: Back + errors: + form: + error: Error + index: + create: Create new content block + delete: Delete + title: Content blocks + new: + back: Back + title: Create new content block + content_block: + body: Body + name: Name images: index: title: Custom images @@ -493,7 +519,7 @@ en: pages: create: notice: Page created successfully - error: Process couldn't be created + error: Page couldn't be created update: notice: Page updated successfully error: Page couldn't be updated diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index f4c834e34..feb72e24c 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -210,6 +210,7 @@ es: site_customization: pages: Personalizar páginas images: Personalizar imágenes + content_blocks: Personalizar bloques moderators: index: title: Moderadores @@ -479,6 +480,31 @@ es: sms_code_not_confirmed: No ha introducido su código de seguridad title: Verificaciones incompletas site_customization: + content_blocks: + create: + notice: Bloque creado correctamente + error: No se ha podido crear el bloque + update: + notice: Bloque actualizado correctamente + error: No se ha podido actualizar el bloque + destroy: + notice: Bloque borrado correctamente + edit: + title: Editar bloque + back: Volver + errors: + form: + error: Error + index: + create: Crear nuevo bloque + delete: Borrar + title: Bloques + new: + back: Volver + title: Crear nuevo bloque + content_block: + body: Contenido + name: Nombre images: index: title: Personalizar imágenes diff --git a/config/routes.rb b/config/routes.rb index 51d2a47da..2088c48da 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -226,6 +226,7 @@ Rails.application.routes.draw do namespace :site_customization do resources :pages, except: [:show] resources :images, only: [:index, :update, :destroy] + resources :content_blocks, except: [:show] end end diff --git a/db/migrate/20170324101716_create_site_customization_content_blocks.rb b/db/migrate/20170324101716_create_site_customization_content_blocks.rb new file mode 100644 index 000000000..d0e4c3822 --- /dev/null +++ b/db/migrate/20170324101716_create_site_customization_content_blocks.rb @@ -0,0 +1,13 @@ +class CreateSiteCustomizationContentBlocks < ActiveRecord::Migration + def change + create_table :site_customization_content_blocks do |t| + t.string :name + t.string :locale + t.text :body + + t.timestamps null: false + end + + add_index :site_customization_content_blocks, [:name, :locale], unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 938fbb9ec..e92a4121c 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: 20170322145702) do +ActiveRecord::Schema.define(version: 20170324101716) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -439,6 +439,16 @@ ActiveRecord::Schema.define(version: 20170322145702) do t.datetime "updated_at" end + create_table "site_customization_content_blocks", force: :cascade do |t| + t.string "name" + t.string "locale" + t.text "body" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "site_customization_content_blocks", ["name", "locale"], name: "index_site_customization_content_blocks_on_name_and_locale", unique: true, using: :btree + create_table "site_customization_images", force: :cascade do |t| t.string "name", null: false t.string "image_file_name" diff --git a/db/seeds.rb b/db/seeds.rb index be7960dff..bbbf0eb01 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -51,6 +51,8 @@ Setting["facebook_handle"] = nil Setting["youtube_handle"] = nil Setting["telegram_handle"] = nil Setting["blog_url"] = nil +Setting["transparency_url"] = nil +Setting["opendata_url"] = "/opendata" # Public-facing URL of the app. Setting["url"] = "http://example.com" diff --git a/spec/factories.rb b/spec/factories.rb index 20a1f463c..116b612d5 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -468,4 +468,10 @@ FactoryGirl.define do more_info_flag true end end + + factory :site_customization_content_block, class: 'SiteCustomization::ContentBlock' do + name "top_links" + locale "en" + body "Some top links content" + end end diff --git a/spec/features/admin/site_customization/content_blocks_spec.rb b/spec/features/admin/site_customization/content_blocks_spec.rb new file mode 100644 index 000000000..cc5dca34c --- /dev/null +++ b/spec/features/admin/site_customization/content_blocks_spec.rb @@ -0,0 +1,107 @@ +require 'rails_helper' + +feature "Admin custom content blocks" do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Index" do + block = create(:site_customization_content_block) + visit admin_site_customization_content_blocks_path + + expect(page).to have_content(block.name) + expect(page).to have_content(block.body) + end + + context "Create" do + scenario "Valid custom block" do + visit admin_root_path + + within("#side_menu") do + click_link "Custom content blocks" + end + + expect(page).to_not have_content "footer (es)" + + click_link "Create new content block" + + select "footer", from: "site_customization_content_block_name" + select "es", from: "site_customization_content_block_locale" + fill_in "site_customization_content_block_body", with: "Some custom content" + + click_button "Create Custom content block" + + expect(page).to have_content "footer (es)" + expect(page).to have_content "Some custom content" + end + + scenario "Invalid custom block" do + block = create(:site_customization_content_block) + + visit admin_root_path + + within("#side_menu") do + click_link "Custom content blocks" + end + + expect(page).to have_content "top_links (en)" + + click_link "Create new content block" + + select "top_links", from: "site_customization_content_block_name" + select "en", from: "site_customization_content_block_locale" + fill_in "site_customization_content_block_body", with: "Some custom content" + + click_button "Create Custom content block" + + expect(page).to have_content "Content block couldn't be created" + expect(page).to have_content "has already been taken" + end + end + + context "Update" do + scenario "Valid custom block" do + block = create(:site_customization_content_block) + visit admin_root_path + + within("#side_menu") do + click_link "Custom content blocks" + end + + click_link "top_links (en)" + + fill_in "site_customization_content_block_body", with: "Some other custom content" + click_button "Update Custom content block" + + expect(page).to have_content "Content block updated successfully" + expect(page).to have_content "Some other custom content" + end + end + + context "Delete" do + scenario "From index page" do + block = create(:site_customization_content_block) + visit admin_site_customization_content_blocks_path + + expect(page).to have_content("#{block.name} (#{block.locale})") + expect(page).to have_content(block.body) + + click_button "Delete" + + expect(page).to_not have_content("#{block.name} (#{block.locale})") + expect(page).to_not have_content(block.body) + end + + scenario "From edit page" do + block = create(:site_customization_content_block) + visit edit_admin_site_customization_content_block_path(block) + + click_button "Delete" + + expect(page).to_not have_content("#{block.name} (#{block.locale})") + expect(page).to_not have_content(block.body) + end + end +end diff --git a/spec/features/site_customization/content_blocks_spec.rb b/spec/features/site_customization/content_blocks_spec.rb new file mode 100644 index 000000000..995982063 --- /dev/null +++ b/spec/features/site_customization/content_blocks_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +feature "Custom content blocks" do + scenario "top links" do + create(:site_customization_content_block, name: "top_links", locale: "en", body: "content for top links") + create(:site_customization_content_block, name: "top_links", locale: "es", body: "contenido para top links") + + visit "/?locale=en" + + expect(page).to have_content("content for top links") + expect(page).to_not have_content("contenido para top links") + + visit "/?locale=es" + + expect(page).to have_content("contenido para top links") + expect(page).to_not have_content("content for top links") + end + + scenario "footer" do + create(:site_customization_content_block, name: "footer", locale: "en", body: "content for footer") + create(:site_customization_content_block, name: "footer", locale: "es", body: "contenido para footer") + + visit "/?locale=en" + + expect(page).to have_content("content for footer") + expect(page).to_not have_content("contenido para footer") + + visit "/?locale=es" + + expect(page).to have_content("contenido para footer") + expect(page).to_not have_content("content for footer") + end +end diff --git a/spec/models/site_customization/content_block_spec.rb b/spec/models/site_customization/content_block_spec.rb new file mode 100644 index 000000000..2eb6279f6 --- /dev/null +++ b/spec/models/site_customization/content_block_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +RSpec.describe SiteCustomization::ContentBlock, type: :model do + let(:block) { build(:site_customization_content_block) } + + it "should be valid" do + expect(block).to be_valid + end + + it "name is unique per locale" do + create(:site_customization_content_block, name: "top_links", locale: "en") + invalid_block = build(:site_customization_content_block, name: "top_links", locale: "en") + + expect(invalid_block).to be_invalid + expect(invalid_block.errors.full_messages).to include("Name has already been taken") + + valid_block = build(:site_customization_content_block, name: "top_links", locale: "es") + expect(valid_block).to be_valid + end +end From d5669fbbaecefe065b9674a3696a46019577587d Mon Sep 17 00:00:00 2001 From: Fernando Blat Date: Thu, 6 Apr 2017 08:11:03 +0200 Subject: [PATCH 535/613] Add settings translation --- config/locales/settings.en.yml | 2 ++ config/locales/settings.es.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/config/locales/settings.en.yml b/config/locales/settings.en.yml index 7e126bc35..72aa390db 100755 --- a/config/locales/settings.en.yml +++ b/config/locales/settings.en.yml @@ -20,6 +20,8 @@ en: facebook_handle: "Facebook handle" youtube_handle: "Youtube handle" blog_url: "Blog URL" + transparency_url: "Transparency URL" + opendata_url: "Open Data URL" url: "Main URL" org_name: "Organization" place_name: "Place" diff --git a/config/locales/settings.es.yml b/config/locales/settings.es.yml index 27224d90b..afb48d799 100644 --- a/config/locales/settings.es.yml +++ b/config/locales/settings.es.yml @@ -20,6 +20,8 @@ es: facebook_handle: "Identificador de Facebook" youtube_handle: "Usuario de Youtube" blog_url: "URL del blog" + transparency_url: "URL de transparencia" + opendata_url: "URL de open data" url: "URL general de la web" org_name: "Nombre de la organización" place_name: "Nombre del lugar" From 3a275ea8506a744f74aef6d98f58fcbbc8a9f37e Mon Sep 17 00:00:00 2001 From: Fernando Blat Date: Thu, 6 Apr 2017 08:20:24 +0200 Subject: [PATCH 536/613] Use open data setting in footer links --- app/views/layouts/_footer.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 1e5c3dfa5..55ff90bf3 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -32,7 +32,7 @@

    - <%= link_to t("layouts.footer.open_data_title"), "/opendata" %> + <%= link_to t("layouts.footer.open_data_title"), setting['opendata_url'].presence || t("layouts.header.external_link_opendata_url") %>

    <%= t("layouts.footer.open_data_text") %>

    From e126a2ded0ad275e47063c3c5bb98cbfc89b8351 Mon Sep 17 00:00:00 2001 From: Fernando Blat Date: Thu, 6 Apr 2017 08:37:46 +0200 Subject: [PATCH 537/613] Add information about content blocks --- .../content_blocks/_form.html.erb | 15 ++++++++++++++- config/locales/admin.en.yml | 5 +++++ config/locales/admin.es.yml | 5 +++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb index 9ca4eb36a..b5a692d87 100644 --- a/app/views/admin/site_customization/content_blocks/_form.html.erb +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -15,7 +15,6 @@ <% end %> -
    <%= f.label :name %> <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS, label: false %> @@ -32,3 +31,17 @@
    <% end %> + +

    <%= t('.content_blocks_information') %>

    + +

    <%= t('.content_block_about') %>

    + +

    <%= t('.content_block_top_links_html') %>

    +
    +<li><a href="http://site1.com">Site 1</a></li>
    +<li><a href="http://site2.com">Site 2</a></li>
    +<li><a href="http://site3.com">Site 3</a></li>
    +
    +
    + +

    <%= t('.content_block_footer_html') %>

    diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 12911c410..4ad60f2a4 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -481,6 +481,11 @@ en: title: Incomplete verifications site_customization: content_blocks: + form: + content_blocks_information: Information about content blocks + content_block_about: You can create HTML content blocks to be inserted in the header or the footer of your Consul. + content_block_top_links_html: "Header blocks (top_links) are blocks of links that must have this format:" + content_block_footer_html: "Footer blocks can have any format and can be used to insert Javascript, CSS or custom HTML." create: notice: Content block created successfully error: Content block couldn't be created diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index feb72e24c..96ff667df 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -481,6 +481,11 @@ es: title: Verificaciones incompletas site_customization: content_blocks: + form: + content_blocks_information: Información sobre los bloques de texto + content_block_about: Puedes crear bloques de HTML que se incrustarán en la cabecera o el pie de tu Cónsul. + content_block_top_links_html: "Los bloques de la cabecera (top_links) son bloques de enlaces que deben crearse con este formato:" + content_block_footer_html: "Los bloques del pie (footer) pueden tener cualquier formato y se pueden utilizar para guardar huellas Javascript, contenido CSS o contenido HTML personalizado." create: notice: Bloque creado correctamente error: No se ha podido crear el bloque From b0b39d9f8a93c80425598746c691aac2e24a86ae Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Thu, 6 Apr 2017 16:05:09 +0200 Subject: [PATCH 538/613] Remove sandbox Revert "Implement Sandbox" This reverts commit e806a39820c2920d18b80dc560d05db36ecb6ede. --- app/controllers/sandbox_controller.rb | 45 --------------------------- app/views/sandbox/index.html.erb | 13 -------- config/routes.rb | 5 --- 3 files changed, 63 deletions(-) delete mode 100644 app/controllers/sandbox_controller.rb delete mode 100644 app/views/sandbox/index.html.erb diff --git a/app/controllers/sandbox_controller.rb b/app/controllers/sandbox_controller.rb deleted file mode 100644 index 12b5dd91e..000000000 --- a/app/controllers/sandbox_controller.rb +++ /dev/null @@ -1,45 +0,0 @@ -class SandboxController < ApplicationController - skip_authorization_check - - layout :set_layout - - helper_method(:namespace) - - def index - @templates = Dir.glob(Rails.root.join('app/views/sandbox/*.html.erb').to_s).map do |filename| - filename = File.basename(filename, File.extname(filename)) - filename unless filename.starts_with?('_') || filename == 'index.html' - end.compact - end - - def show - if params[:template].index('.') # CVE-2014-0130 - render :action => "index" - elsif lookup_context.exists?("sandbox/#{params[:template]}") - if params[:template] == "index" - render :action => "index" - else - render "sandbox/#{params[:template]}" - end - - elsif lookup_context.exists?("sandbox/#{params[:template]}/index") - render "sandbox/#{params[:template]}/index" - else - render :action => "index" - end - end - - private - - def set_layout - if params[:template] && params[:template].split("_").first == "admin" - "admin" - else - "application" - end - end - - def namespace - "admin" - end -end diff --git a/app/views/sandbox/index.html.erb b/app/views/sandbox/index.html.erb deleted file mode 100644 index 9d6303698..000000000 --- a/app/views/sandbox/index.html.erb +++ /dev/null @@ -1,13 +0,0 @@ -
    -
    -
    -

    Welcome to sandbox

    - -
      - <% @templates.each do |template| %> -
    • <%= link_to template, "/sandbox/" + template %>
    • - <% end %> -
    -
    -
    -
    diff --git a/config/routes.rb b/config/routes.rb index 2088c48da..63b04458b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,10 +1,5 @@ Rails.application.routes.draw do - if Rails.env.development? || Rails.env.staging? - get '/sandbox' => 'sandbox#index' - get '/sandbox/*template' => 'sandbox#show' - end - devise_for :users, controllers: { registrations: 'users/registrations', sessions: 'users/sessions', From 613f5521a2d40db269bf42f37cec3a9058299ee2 Mon Sep 17 00:00:00 2001 From: Amaia Castro Date: Thu, 6 Apr 2017 17:24:09 +0200 Subject: [PATCH 539/613] Put footer block inside row div --- app/views/layouts/_footer.html.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 55ff90bf3..0bce1cd67 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -97,5 +97,7 @@
    - <%= raw content_block("footer", I18n.locale) %> +
    + <%= raw content_block("footer", I18n.locale) %> +
    From 3d45c0ca1af65b56e488143b040fc7c948f0605a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 6 Apr 2017 18:34:50 +0200 Subject: [PATCH 540/613] adds telegram handle to dev seeds and admin settings --- config/locales/settings.en.yml | 1 + config/locales/settings.es.yml | 1 + db/dev_seeds.rb | 1 + 3 files changed, 3 insertions(+) diff --git a/config/locales/settings.en.yml b/config/locales/settings.en.yml index 7e126bc35..f2807f303 100755 --- a/config/locales/settings.en.yml +++ b/config/locales/settings.en.yml @@ -19,6 +19,7 @@ en: twitter_hashtag: "Twitter hashtag" facebook_handle: "Facebook handle" youtube_handle: "Youtube handle" + telegram_handle: "Telegram handle" blog_url: "Blog URL" url: "Main URL" org_name: "Organization" diff --git a/config/locales/settings.es.yml b/config/locales/settings.es.yml index 27224d90b..b19b1046d 100644 --- a/config/locales/settings.es.yml +++ b/config/locales/settings.es.yml @@ -19,6 +19,7 @@ es: twitter_hashtag: "Hashtag para Twitter" facebook_handle: "Identificador de Facebook" youtube_handle: "Usuario de Youtube" + telegram_handle: "Usuario de Telegram" blog_url: "URL del blog" url: "URL general de la web" org_name: "Nombre de la organización" diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index eb1651a0c..841c76bbe 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -20,6 +20,7 @@ Setting.create(key: 'twitter_handle', value: '@consul_dev') Setting.create(key: 'twitter_hashtag', value: '#consul_dev') Setting.create(key: 'facebook_handle', value: 'consul') Setting.create(key: 'youtube_handle', value: 'consul') +Setting.create(key: 'telegram_handle', value: 'consul') Setting.create(key: 'blog_url', value: '/blog') Setting.create(key: 'url', value: 'http://localhost:3000') Setting.create(key: 'org_name', value: 'Consul') From e2cbdfe48069fa6acc226f51d80ace348d17bf69 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 7 Apr 2017 18:30:30 +0200 Subject: [PATCH 541/613] adds polls section on more info pages --- app/views/pages/more_info/_polls.html.erb | 15 +++++++++++++++ app/views/pages/more_info/index.html.erb | 4 ++++ config/locales/pages.en.yml | 7 +++++++ config/locales/pages.es.yml | 7 +++++++ 4 files changed, 33 insertions(+) create mode 100644 app/views/pages/more_info/_polls.html.erb diff --git a/app/views/pages/more_info/_polls.html.erb b/app/views/pages/more_info/_polls.html.erb new file mode 100644 index 000000000..360558d99 --- /dev/null +++ b/app/views/pages/more_info/_polls.html.erb @@ -0,0 +1,15 @@ +
    +
    +

    <%= t("pages.more_info.polls.title") %>

    +

    <%= t("pages.more_info.polls.description") %>

    +
      +
    • + <%= t("pages.more_info.polls.feature_1", + link: link_to(t("pages.more_info.polls.feature_1_link", org_name: setting['org_name']), + new_user_registration_path)).html_safe %> +
    • +
    • <%= t("pages.more_info.polls.feature_2") %>
    • +
    • <%= t("pages.more_info.polls.feature_3") %>
    • +
    +
    +
    diff --git a/app/views/pages/more_info/index.html.erb b/app/views/pages/more_info/index.html.erb index 4c40a9fee..940170ed0 100644 --- a/app/views/pages/more_info/index.html.erb +++ b/app/views/pages/more_info/index.html.erb @@ -24,6 +24,10 @@ <% if feature?(:budgets) %> <%= render "pages/more_info/budgets" %> <% end %> + + <% if feature?(:polls) %> + <%= render "pages/more_info/polls" %> + <% end %>
    <%= render "pages/more_info/sidebar" %> diff --git a/config/locales/pages.en.yml b/config/locales/pages.en.yml index a8e8a1b47..c2a3a18fc 100755 --- a/config/locales/pages.en.yml +++ b/config/locales/pages.en.yml @@ -42,6 +42,13 @@ en: feature_4_html: "At the end there is a voting phase where it is decided on which part of the budget is spent." image_alt: "Different phases of a participatory budget" figcaption_html: '"Support phase" and "Voting" phase of participatory budgets.' + polls: + title: "Polls" + description: "Citizen proposals that reach 1% of support will be put to a vote." + feature_1: "To participate in the next poll you have to %{link} and verify your account." + feature_1_link: "sign up on %{org_name}" + feature_2: "All verified users over 16 years old can vote." + feature_3: "The results of all votes shall be binding on the government." faq: title: "Technical problems?" description: "Read the FAQs and solve your questions." diff --git a/config/locales/pages.es.yml b/config/locales/pages.es.yml index 652f03852..77591e697 100644 --- a/config/locales/pages.es.yml +++ b/config/locales/pages.es.yml @@ -42,6 +42,13 @@ es: feature_4_html: "Al final hay una fase de votación donde se decide en cuáles se gasta esa parte del presupuesto." image_alt: "Diferentes fases de un presupuesto participativo" figcaption_html: 'Fase de "Apoyos" y fase de "Votación" de los presupuestos participativos.' + polls: + title: "Votaciones" + description: "Las propuestas ciudadanas que alcancen el 1% de apoyos pasarán a votación." + feature_1: "Para participar en la próxima votación tienes que %{link} y verificar tu cuenta." + feature_1_link: "registrarte en %{org_name}" + feature_2: "Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años." + feature_3: "Los resultados de todas las votaciones serán vinculantes para el gobierno." faq: title: "¿Problemas técnicos?" description: "Lee las preguntas frecuentes y resuelve tus dudas." From 910d615017611d51ffec7f00931d2e5c93acb5b1 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 7 Apr 2017 18:33:26 +0200 Subject: [PATCH 542/613] removes details page info of proposals and budgets --- app/views/pages/more_info/_budgets.html.erb | 3 -- app/views/pages/more_info/_proposals.html.erb | 3 -- app/views/pages/more_info/budgets/index.html | 15 ---------- .../pages/more_info/proposals/index.html.erb | 28 ------------------- config/locales/pages.en.yml | 2 -- config/locales/pages.es.yml | 2 -- config/routes.rb | 2 -- 7 files changed, 55 deletions(-) delete mode 100644 app/views/pages/more_info/budgets/index.html delete mode 100644 app/views/pages/more_info/proposals/index.html.erb diff --git a/app/views/pages/more_info/_budgets.html.erb b/app/views/pages/more_info/_budgets.html.erb index b2f34d690..6450bdffe 100644 --- a/app/views/pages/more_info/_budgets.html.erb +++ b/app/views/pages/more_info/_budgets.html.erb @@ -3,9 +3,6 @@

    <%= t("pages.more_info.budgets.title") %>

    -

    - <%= link_to t("pages.more_info.budgets.detail"), more_info_budgets_path, class: "small" %> -

    <%= t("pages.more_info.budgets.description") %>

    • diff --git a/app/views/pages/more_info/_proposals.html.erb b/app/views/pages/more_info/_proposals.html.erb index b93acfa62..cf1822142 100644 --- a/app/views/pages/more_info/_proposals.html.erb +++ b/app/views/pages/more_info/_proposals.html.erb @@ -3,9 +3,6 @@

      <%= t("pages.more_info.proposals.title") %>

      -

      - <%= link_to t("pages.more_info.proposals.detail"), more_info_proposals_path, class: "small" %> -

      <%= t("pages.more_info.proposals.description") %>

      • diff --git a/app/views/pages/more_info/budgets/index.html b/app/views/pages/more_info/budgets/index.html deleted file mode 100644 index 41332bb96..000000000 --- a/app/views/pages/more_info/budgets/index.html +++ /dev/null @@ -1,15 +0,0 @@ -
        -
        - <%= render "shared/back_link" %> - - -
        - -
        -

        ¿Cómo funcionan los Presupuestos participativos?

        -

        Explicación detallada del proceso

        -

        Descripción del proceso de participación ciudadana en los presupuestos.

        -
        -
        diff --git a/app/views/pages/more_info/proposals/index.html.erb b/app/views/pages/more_info/proposals/index.html.erb deleted file mode 100644 index 09bf8585e..000000000 --- a/app/views/pages/more_info/proposals/index.html.erb +++ /dev/null @@ -1,28 +0,0 @@ -
        -
        - <%= render "shared/back_link" %> - - -
        - -
        -

        ¿Cómo funcionan las propuestas ciudadanas?

        -

        El mecanismo de propuestas ciudadanas se resume en cuatro pasos muy sencillos:

        -
          -
        1. ¡Propones! Creas una propuesta en esta web.
        2. -
        3. ¡Apoyas! La gente hace clic en el botón de apoyar tu propuesta (necesitas el apoyo del 2% de los empadronados mayores de 16 años para pasar a la siguiente fase).
        4. -
        5. ¡Decides! Si has conseguido suficientes apoyos, dejamos 45 días para que la gente pueda debatir sobre la propuesta, y después durante una semana se invita a toda la gente empadronada a decidir si están a favor o en contra de tu propuesta, en esta misma web.
        6. -
        7. ¡Se hace! Si hay más gente a favor de tu propuesta que en contra, el gobierno del Ayuntamiento asumirá como propia la propuesta y la llevará a cabo.
        8. -
        - -

        Explicación detallada del proceso

        -
          -
        1. Creación de una propuesta. Cualquier persona (sin necesidad siquiera de estar empadronada) puede crear una propuesta. Lo único que hay que hacer es pulsar el botón “Crear una propuesta” y rellenar los campos requeridos. La propuesta puede ser tan sencilla como una simple frase, pero te recomendamos detallarla todo lo posible, incluso añadiendo material adicional, para que sea más completa e interesante. Una vez creada aparecerá en esta web para que cualquiera pueda apoyarla.
        2. -
        3. Apoyo de propuestas. Para apoyar una de las propuestas que aparece en la web, pulsamos el botón “apoyar esta propuesta” que aparece en cada una. Para este paso tendremos que estar empadronados, así que al llevarlo a cabo por primera vez se nos pedirá que verifiquemos nuestra cuenta para estar seguros de este requerimiento. Se nos va a pedir que introduzcamos algunos datos para comprobar nuestra información de empadronamiento, y se nos enviará un código personal para que el proceso sea seguro. Las propuestas necesitan una cierta cantidad de apoyos para pasar a la siguiente fase; concretamente el 2% de los empadronados mayores de 16 años.
        4. -
        5. Decisión sobre propuestas. Cuando una propuesta consigue los apoyos necesarios, se anuncia en la web. Desde ese momento se dejan 45 días para que todo el mundo pueda debatir e informarse sobre la propuesta. Todas las otras propuestas que hayan conseguido los apoyos necesarios en los primeros 30 días del tiempo de debate se agruparán junto a la primera para decidir sobre ellas al mismo tiempo. Pasados los 45 días se exponen estas propuestas en un espacio especial de votación de la web, donde durante una semana cualquier persona empadronada y mayor de 16 años podrá decidir si está a favor o rechaza la propuesta. Para participar en este paso tendrás que tener tu cuenta de usuario verificada completamente, de tal forma que nos aseguremos que cada persona no tiene más de una cuenta y el proceso es seguro.
        6. -
        7. Realización de las propuestas. En caso de que haya más gente a favor de una propuesta que rechazándola se aceptará como propuesta colectiva de la ciudadanía, y el gobierno del Ayuntamiento la asumirá como propia y la llevará a cabo. Para ello en un plazo máximo de un mes, se realizarán los informes técnicos correspondientes sobre su legalidad, viabilidad y coste económico, teniendo en cuenta a los sectores afectados y a la persona que haya lanzado la propuesta, para detallar la actuación correspondiente por parte del Ayuntamiento. Se publicarán en la web todos los informes realizados, y un seguimiento de las actuaciones que se lleven a cabo, para asegurar un correcto desarrollo de la propuesta.
        8. -
        -
        -
        diff --git a/config/locales/pages.en.yml b/config/locales/pages.en.yml index c2a3a18fc..e3fd3ec7f 100755 --- a/config/locales/pages.en.yml +++ b/config/locales/pages.en.yml @@ -24,7 +24,6 @@ en: proposals: title: "Proposals" description: "Propose what you want the City Council to carry out and support proposals from other people." - detail: "Detailed information of proposals" feature_1: "To create a proposal you have to %{link}, in addition to support you must verify your account." feature_1_link: "sign up on %{org_name}" feature_2_html: "Proposals that get support from 1% of people will be voted on." @@ -34,7 +33,6 @@ en: budgets: title: "Participatory Budgeting" description: "The first six months of each year you can decide how to spend part of the budget." - detail: "Detailed information of Participatory Budgeting" feature_1: "To create an investment project you have to %{link} and verify your account." feature_1_link: "sign up on %{org_name}" feature_2_html: "The first is the accepting phase of investment projects." diff --git a/config/locales/pages.es.yml b/config/locales/pages.es.yml index 77591e697..27f1afc16 100644 --- a/config/locales/pages.es.yml +++ b/config/locales/pages.es.yml @@ -24,7 +24,6 @@ es: proposals: title: "Propuestas" description: "Propón lo que quieres que el Ayuntamiento lleve a cabo y apoya propuestas de otras personas." - detail: "Información detallada de Propuestas" feature_1: "Para crear una propuesta tienes que %{link}, además para apoyarlas debes verificar tu cuenta." feature_1_link: "registrarte en %{org_name}" feature_2_html: "Las propuestas que consigan el apoyo del 1% de la gente (mayor de 16 años empadronada en Madrid; 27.064 apoyos) pasan a votación." @@ -34,7 +33,6 @@ es: budgets: title: "Presupuestos participativos" description: "Los primeros seis meses de cada año puedes decidir cómo gastar parte del presupuesto." - detail: "Información detallada de Presupuestos participativos" feature_1: "Para crear un proyecto de gasto tienes que %{link} y verificar tu cuenta." feature_1_link: "registrarte en %{org_name}" feature_2_html: "En primer lugar empieza la fase de aceptación de proyectos de gasto." diff --git a/config/routes.rb b/config/routes.rb index 48062f779..cffd0a113 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -359,8 +359,6 @@ Rails.application.routes.draw do get 'more-information', to: 'pages#show', id: 'more_info/index', as: 'more_info' get 'more-information/how-to-use', to: 'pages#show', id: 'more_info/how_to_use/index', as: 'how_to_use' get 'more-information/faq', to: 'pages#show', id: 'more_info/faq/index', as: 'faq' - get 'more-information/proposals', to: 'pages#show', id: 'more_info/proposals/index', as: 'more_info_proposals' - get 'more-information/budgets', to: 'pages#show', id: 'more_info/budgets/index', as: 'more_info_budgets' get 'more-information/participation/facts', to: 'pages#show', id: 'more_info/participation/facts', as: 'participation_facts' get 'more-information/participation/world', to: 'pages#show', id: 'more_info/participation/world', as: 'participation_world' From b341a5538e44694a2accd88570c137d336cee584 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 11 Apr 2017 17:00:08 +0200 Subject: [PATCH 543/613] improves english i18n to more info pages --- config/locales/pages.en.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/pages.en.yml b/config/locales/pages.en.yml index e3fd3ec7f..a7b4ca43c 100755 --- a/config/locales/pages.en.yml +++ b/config/locales/pages.en.yml @@ -27,17 +27,17 @@ en: feature_1: "To create a proposal you have to %{link}, in addition to support you must verify your account." feature_1_link: "sign up on %{org_name}" feature_2_html: "Proposals that get support from 1% of people will be voted on." - feature_3_html: "If there are more people in favor of against, the City Council assumes the proposal and it is done." + feature_3_html: "If there are more people in favor than against, the City Council will publish their plan to accomplish the proposal and you can track its progress." image_alt: "Button to support a proposal" figcaption_html: 'Button to "Support" a proposal.
        When it reaches the number of supports will go to vote.' budgets: title: "Participatory Budgeting" description: "The first six months of each year you can decide how to spend part of the budget." - feature_1: "To create an investment project you have to %{link} and verify your account." + feature_1: "To submit an investment project you have to %{link} and verify your account." feature_1_link: "sign up on %{org_name}" - feature_2_html: "The first is the accepting phase of investment projects." + feature_2_html: "The first is the submit phase of investment projects." feature_3_html: "Then there is a support phase to prioritize the most interesting, the most supported are evaluated by the City to see if they are viable and how much they are worth." - feature_4_html: "At the end there is a voting phase where it is decided on which part of the budget is spent." + feature_4_html: "At the end there is a vote phase where it is decided on which part of the budget is spent." image_alt: "Different phases of a participatory budget" figcaption_html: '"Support phase" and "Voting" phase of participatory budgets.' polls: From 61e5c187da200cbffac8e77c1a14cbac21ad3194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 17 Apr 2017 13:15:17 +0200 Subject: [PATCH 544/613] shows investment price info only if phase is balloting or later --- app/models/budget/investment.rb | 6 ++++ .../investments/_investment_show.html.erb | 2 +- spec/models/budget/investment_spec.rb | 34 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 4bfd038c3..0a7e92344 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -245,6 +245,12 @@ class Budget budget.balloting? end + def should_show_price_info? + feasible? && + price_explanation.present? && + (budget.balloting? || budget.reviewing_ballots? || budget.finished?) + end + def formatted_price budget.formatted_amount(price) end diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index d97a1fbfb..f88869cb9 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -47,7 +47,7 @@

        <%= investment.unfeasibility_explanation %>

        <% end %> - <% if investment.feasible? && investment.price_explanation.present? %> + <% if investment.should_show_price_info? %>

        <%= t('budgets.investments.show.price_explanation') %>

        <%= investment.price_explanation %>

        <% end %> diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index fa51f3cab..47affc10c 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -144,6 +144,40 @@ describe Budget::Investment do end end + describe "#should_show_price_info?" do + it "returns true for feasibles if phase is balloting or later and price_explanation is present" do + ["balloting", "reviewing_ballots", "finished"].each do |phase| + budget = create(:budget, phase: phase) + investment = create(:budget_investment, :feasible, budget: budget, price_explanation: "price explanation") + + expect(investment.should_show_price_info?).to eq(true) + end + end + + it "returns false in any other phase" do + (Budget::PHASES - ["balloting", "reviewing_ballots", "finished"]).each do |phase| + budget = create(:budget, phase: phase) + investment = create(:budget_investment, :feasible, budget: budget, price_explanation: "price explanation") + + expect(investment.should_show_price_info?).to eq(false) + end + end + + it "returns false if investment is unfeasible" do + budget = create(:budget, phase: "balloting") + investment = create(:budget_investment, :unfeasible, budget: budget, price_explanation: "price explanation") + + expect(investment.should_show_price_info?).to eq(false) + end + + it "returns false if price_explanation is blank" do + budget = create(:budget, phase: "balloting") + investment = create(:budget_investment, :unfeasible, budget: budget, price_explanation: "") + + expect(investment.should_show_price_info?).to eq(false) + end + end + describe "by_admin" do it "should return investments assigned to specific administrator" do investment1 = create(:budget_investment, administrator_id: 33) From 3f0485462612c70f4695c388f5998572c9e25e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 17 Apr 2017 13:17:01 +0200 Subject: [PATCH 545/613] adds missing method specs --- spec/models/budget/investment_spec.rb | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index 47affc10c..e9d5ccd13 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -144,6 +144,42 @@ describe Budget::Investment do end end + describe "#should_show_vote_count?" do + it "returns true in valuating phase" do + budget = create(:budget, phase: "valuating") + investment = create(:budget_investment, budget: budget) + + expect(investment.should_show_vote_count?).to eq(true) + end + + it "returns false in any other phase" do + Budget::PHASES.reject {|phase| phase == "valuating"}.each do |phase| + budget = create(:budget, phase: phase) + investment = create(:budget_investment, budget: budget) + + expect(investment.should_show_vote_count?).to eq(false) + end + end + end + + describe "#should_show_ballots?" do + it "returns true in balloting phase" do + budget = create(:budget, phase: "balloting") + investment = create(:budget_investment, budget: budget) + + expect(investment.should_show_ballots?).to eq(true) + end + + it "returns false in any other phase" do + Budget::PHASES.reject {|phase| phase == "balloting"}.each do |phase| + budget = create(:budget, phase: phase) + investment = create(:budget_investment, budget: budget) + + expect(investment.should_show_ballots?).to eq(false) + end + end + end + describe "#should_show_price_info?" do it "returns true for feasibles if phase is balloting or later and price_explanation is present" do ["balloting", "reviewing_ballots", "finished"].each do |phase| From 0bc260a10584a3bf7bdf7188b94837cd57f15bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 17 Apr 2017 13:31:31 +0200 Subject: [PATCH 546/613] adds feature spec for price explanation visibility --- spec/features/budgets/investments_spec.rb | 48 +++++++++++++++-------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 5446e0a0a..8a817a805 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -188,7 +188,7 @@ feature 'Budget Investments' do expect(current_path).to eq(budget_investments_path(budget_id: budget.id)) end - scenario 'Create spending proposal too fast' do + scenario 'Create budget investment too fast' do allow(InvisibleCaptcha).to receive(:timestamp_threshold).and_return(Float::INFINITY) login_as(author) @@ -263,26 +263,40 @@ feature 'Budget Investments' do end end - scenario "Show (feasible spending proposal)" do - user = create(:user) - login_as(user) + context "Show (feasible budget investment)" do + let(:investment) { create(:budget_investment, + :feasible, + :finished, + budget: budget, + group: group, + heading: heading, + price: 16, + price_explanation: 'Every wheel is 4 euros, so total is 16')} - investment = create(:budget_investment, - :feasible, - :finished, - budget: budget, - group: group, - heading: heading, - price: 16, - price_explanation: 'Every wheel is 4 euros, so total is 16') + background do + user = create(:user) + login_as(user) + end - visit budget_investment_path(budget_id: budget.id, id: investment.id) + scenario "Budget in selecting phase" do + budget.update(phase: "selecting") + visit budget_investment_path(budget_id: budget.id, id: investment.id) - expect(page).to have_content("Price explanation") - expect(page).to have_content(investment.price_explanation) + expect(page).to_not have_content("Unfeasibility explanation") + expect(page).to_not have_content("Price explanation") + expect(page).to_not have_content(investment.price_explanation) + end + + scenario "Budget in balloting phase" do + budget.update(phase: "balloting") + visit budget_investment_path(budget_id: budget.id, id: investment.id) + + expect(page).to have_content("Price explanation") + expect(page).to have_content(investment.price_explanation) + end end - scenario "Show (unfeasible spending proposal)" do + scenario "Show (unfeasible budget investment)" do user = create(:user) login_as(user) @@ -302,7 +316,7 @@ feature 'Budget Investments' do context "Destroy" do - scenario "Admin cannot destroy spending proposals" do + scenario "Admin cannot destroy budget investments" do admin = create(:administrator) user = create(:user, :level_two) investment = create(:budget_investment, heading: heading, author: user) From cb60fb5a14bec07d236a3ad3a4934298c1b959a5 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Apr 2017 17:48:38 +0200 Subject: [PATCH 547/613] changes menu order --- app/views/admin/_menu.html.erb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/views/admin/_menu.html.erb b/app/views/admin/_menu.html.erb index fecd29419..0b9929f46 100644 --- a/app/views/admin/_menu.html.erb +++ b/app/views/admin/_menu.html.erb @@ -129,20 +129,6 @@
    • -
    • > - <%= link_to admin_geozones_path do %> - <%= t('admin.menu.geozones') %> - <% end %> -
    • - - <% if feature?(:signature_sheets) %> -
    • > - <%= link_to admin_signature_sheets_path do %> - <%= t("admin.menu.signature_sheets") %> - <% end %> -
    • - <% end %> -
    • @@ -162,5 +148,19 @@
    + +
  • > + <%= link_to admin_geozones_path do %> + <%= t('admin.menu.geozones') %> + <% end %> +
  • + + <% if feature?(:signature_sheets) %> +
  • > + <%= link_to admin_signature_sheets_path do %> + <%= t("admin.menu.signature_sheets") %> + <% end %> +
  • + <% end %>
    From b5e1ba9a53898c2103f8bc1fa942efc9e853bd3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 17 Apr 2017 18:55:19 +0200 Subject: [PATCH 548/613] updates gems --- Gemfile | 14 +++++++------- Gemfile.lock | 44 ++++++++++++++++++++++---------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Gemfile b/Gemfile index 39dee65f8..0a27ce5bc 100644 --- a/Gemfile +++ b/Gemfile @@ -7,7 +7,7 @@ gem 'pg', '~> 0.20.0' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0', '>= 5.0.4' # Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '~> 3.1.9' +gem 'uglifier', '~> 3.2.0' # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2.1' # See https://github.com/rails/execjs#readme for more supported runtimes @@ -43,8 +43,8 @@ gem 'invisible_captcha', '~> 0.9.2' gem 'cancancan', '~> 1.16.0' gem 'social-share-button', '~> 0.10' gem 'initialjs-rails', '0.2.0.4' -gem 'unicorn', '~> 5.2.0' -gem 'paranoia', '~> 2.2.1' +gem 'unicorn', '~> 5.3.0' +gem 'paranoia', '~> 2.3.0' gem 'rinku', '~> 2.0.2', require: 'rails_rinku' gem 'savon' gem 'dalli' @@ -52,7 +52,7 @@ gem 'rollbar', '~> 2.14.1' gem 'delayed_job_active_record', '~> 4.1.0' gem 'daemons' gem 'devise-async' -gem 'newrelic_rpm', '~> 4.0.0.332' +gem 'newrelic_rpm', '~> 4.1.0.333' gem 'whenever', require: false gem 'pg_search' gem 'sitemap_generator', '~> 5.3.1' @@ -80,7 +80,7 @@ group :development, :test do gem 'launchy' gem 'quiet_assets' gem 'letter_opener_web', '~> 1.3.1' - gem 'i18n-tasks', '~> 0.9.12' + gem 'i18n-tasks', '~> 0.9.13' gem 'capistrano', '~> 3.8.0', require: false gem 'capistrano-bundler', '~> 1.2', require: false gem "capistrano-rails", '~> 1.2.3', require: false @@ -88,14 +88,14 @@ group :development, :test do gem 'capistrano3-delayed-job', '~> 1.7.3' gem "bullet", '~> 5.5.1' gem "faker", '~> 1.7.3' - gem 'rubocop', '~> 0.47.1', require: false + gem 'rubocop', '~> 0.48.1', require: false gem 'knapsack' end group :test do gem 'database_cleaner' gem 'poltergeist', '~> 1.14.0' - gem 'coveralls', '~> 0.8.19', require: false + gem 'coveralls', '~> 0.8.20', require: false gem 'email_spec' end diff --git a/Gemfile.lock b/Gemfile.lock index 67ab5a78b..c5ba5df53 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -110,11 +110,11 @@ GEM execjs coffee-script-source (1.12.2) concurrent-ruby (1.0.5) - coveralls (0.8.19) + coveralls (0.8.20) json (>= 1.8, < 3) - simplecov (~> 0.12.0) + simplecov (~> 0.14.1) term-ansicolor (~> 1.3) - thor (~> 0.19.1) + thor (~> 0.19.4) tins (~> 1.6) daemons (1.2.4) dalli (2.7.6) @@ -185,7 +185,7 @@ GEM httpi (2.4.1) rack i18n (0.8.1) - i18n-tasks (0.9.12) + i18n-tasks (0.9.13) activesupport (>= 4.0.2) ast (>= 2.1.0) easy_translate (>= 0.5.0) @@ -193,7 +193,7 @@ GEM highline (>= 1.7.3) i18n parser (>= 2.2.3.0) - term-ansicolor (>= 1.3.2) + rainbow (~> 2.2) terminal-table (>= 1.5.1) initialjs-rails (0.2.0.4) railties (>= 3.1, < 6.0) @@ -205,7 +205,7 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (6.0.1) railties (>= 3.2.16) - json (2.0.3) + json (2.0.4) jwt (1.5.6) kaminari (1.0.1) activesupport (>= 4.1.0) @@ -220,7 +220,7 @@ GEM kaminari-core (= 1.0.1) kaminari-core (1.0.1) kgio (2.11.0) - knapsack (1.13.2) + knapsack (1.13.3) rake timecop (>= 0.1.0) launchy (2.4.3) @@ -247,7 +247,7 @@ GEM net-scp (1.2.1) net-ssh (>= 2.6.5) net-ssh (4.1.0) - newrelic_rpm (4.0.0.332) + newrelic_rpm (4.1.0.333) nokogiri (1.7.1) mini_portile2 (~> 2.1.0) nori (2.6.0) @@ -284,7 +284,7 @@ GEM cocaine (~> 0.5.5) mime-types mimemagic (~> 0.3.0) - paranoia (2.2.1) + paranoia (2.3.0) activerecord (>= 4.0, < 5.1) parser (2.4.0.0) ast (~> 2.2) @@ -333,7 +333,7 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.2.1) - raindrops (0.17.0) + raindrops (0.18.0) rake (12.0.0) redcarpet (3.4.0) referer-parser (0.3.0) @@ -360,7 +360,7 @@ GEM rspec-mocks (~> 3.5.0) rspec-support (~> 3.5.0) rspec-support (3.5.0) - rubocop (0.47.1) + rubocop (0.48.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) @@ -388,7 +388,7 @@ GEM nokogiri (>= 1.4.0) nori (~> 2.4) wasabi (~> 3.4) - simplecov (0.12.0) + simplecov (0.14.1) docile (~> 1.1.0) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) @@ -415,7 +415,7 @@ GEM sshkit (1.12.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) - term-ansicolor (1.4.0) + term-ansicolor (1.6.0) tins (~> 1.0) terminal-table (1.7.3) unicode-display_width (~> 1.1.1) @@ -437,10 +437,10 @@ GEM tilt (>= 1.4, < 3) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (3.1.9) + uglifier (3.2.0) execjs (>= 0.3.0, < 3) unicode-display_width (1.1.3) - unicorn (5.2.0) + unicorn (5.3.0) kgio (~> 2.6) raindrops (~> 0.7) uniform_notifier (1.10.0) @@ -482,7 +482,7 @@ DEPENDENCIES capybara (~> 2.13.0) ckeditor (~> 4.2.2) coffee-rails (~> 4.2.1) - coveralls (~> 0.8.19) + coveralls (~> 0.8.20) daemons dalli database_cleaner @@ -497,7 +497,7 @@ DEPENDENCIES foundation_rails_helper (~> 2.0.0) fuubar groupdate (~> 3.2.0) - i18n-tasks (~> 0.9.12) + i18n-tasks (~> 0.9.13) initialjs-rails (= 0.2.0.4) invisible_captcha (~> 0.9.2) jquery-rails (~> 4.3.1) @@ -506,13 +506,13 @@ DEPENDENCIES knapsack launchy letter_opener_web (~> 1.3.1) - newrelic_rpm (~> 4.0.0.332) + newrelic_rpm (~> 4.1.0.333) omniauth omniauth-facebook (~> 4.0.0) omniauth-google-oauth2 (~> 0.4.0) omniauth-twitter paperclip - paranoia (~> 2.2.1) + paranoia (~> 2.3.0) pg (~> 0.20.0) pg_search poltergeist (~> 1.14.0) @@ -523,7 +523,7 @@ DEPENDENCIES rinku (~> 2.0.2) rollbar (~> 2.14.1) rspec-rails (~> 3.5) - rubocop (~> 0.47.1) + rubocop (~> 0.48.1) rvm1-capistrano3 sass-rails (~> 5.0, >= 5.0.4) savon @@ -535,8 +535,8 @@ DEPENDENCIES tolk (~> 2.0.0) turbolinks turnout (~> 2.4.0) - uglifier (~> 3.1.9) - unicorn (~> 5.2.0) + uglifier (~> 3.2.0) + unicorn (~> 5.3.0) web-console (= 3.3.0) whenever From 8cbf9f3c3dfd10f63aec5f1137372f835b37869a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Apr 2017 19:02:40 +0200 Subject: [PATCH 549/613] improves site customization layout, tables, i18n --- .../content_blocks/_form.html.erb | 43 +++++------ .../content_blocks/edit.html.erb | 15 ++-- .../content_blocks/index.html.erb | 47 ++++++------ .../content_blocks/new.html.erb | 14 ++-- .../site_customization/images/index.html.erb | 6 ++ .../site_customization/pages/_form.html.erb | 69 ++++++++++-------- .../site_customization/pages/edit.html.erb | 15 ++-- .../site_customization/pages/index.html.erb | 73 ++++++++++--------- .../site_customization/pages/new.html.erb | 14 ++-- config/locales/admin.en.yml | 9 +-- config/locales/admin.es.yml | 10 +-- 11 files changed, 161 insertions(+), 154 deletions(-) diff --git a/app/views/admin/site_customization/content_blocks/_form.html.erb b/app/views/admin/site_customization/content_blocks/_form.html.erb index b5a692d87..ae9d684d4 100644 --- a/app/views/admin/site_customization/content_blocks/_form.html.erb +++ b/app/views/admin/site_customization/content_blocks/_form.html.erb @@ -14,34 +14,35 @@
    <% end %> +
    +
    + <%= f.label :name %> + <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS, label: false %> +
    +
    + <%= f.label :locale %> + <%= f.select :locale, I18n.available_locales, label: false %> +
    -
    - <%= f.label :name %> - <%= f.select :name, SiteCustomization::ContentBlock::VALID_BLOCKS, label: false %> -
    -
    - <%= f.label :locale %> - <%= f.select :locale, I18n.available_locales, label: false %> -
    - -
    - <%= f.label :body %> - <%= f.text_area :body, label: false, rows: 10 %> - <%= f.submit class: "button success" %> +
    + <%= f.label :body %> + <%= f.text_area :body, label: false, rows: 10 %> +
    + <%= f.submit class: "button success expanded" %> +
    +
    <% end %> -

    <%= t('.content_blocks_information') %>

    +

    <%= t('.content_blocks_information') %>

    <%= t('.content_block_about') %>

    <%= t('.content_block_top_links_html') %>

    -
    -<li><a href="http://site1.com">Site 1</a></li>
    -<li><a href="http://site2.com">Site 2</a></li>
    -<li><a href="http://site3.com">Site 3</a></li>
    -
    -
    -

    <%= t('.content_block_footer_html') %>

    +<li><a href="http://site1.com">Site 1</a></li>
    +<li><a href="http://site2.com">Site 2</a></li>
    +<li><a href="http://site3.com">Site 3</a></li>
    + +

    <%= t('.content_block_footer_html') %>

    diff --git a/app/views/admin/site_customization/content_blocks/edit.html.erb b/app/views/admin/site_customization/content_blocks/edit.html.erb index c96f9a810..9c2694449 100644 --- a/app/views/admin/site_customization/content_blocks/edit.html.erb +++ b/app/views/admin/site_customization/content_blocks/edit.html.erb @@ -2,14 +2,13 @@ Admin - <%= t("admin.menu.site_customization.content_blocks") %> - <%= @content_block.name %> (<%= @content_block.locale %>) <% end %> -<%= link_to admin_site_customization_content_blocks_path, class: "back" do %> - - <%= t("admin.site_customization.content_blocks.edit.back") %> -<% end %> +<%= back_link_to admin_site_customization_content_blocks_path %> -<%= button_to t("admin.site_customization.content_blocks.index.delete"), admin_site_customization_content_block_path(@content_block), method: :delete, class: "button hollow alert float-right margin-right" %> +<%= button_to t("admin.site_customization.content_blocks.index.delete"), admin_site_customization_content_block_path(@content_block), method: :delete, class: "button hollow alert float-right small" %> -
    -

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

    - <%= render 'form' %> +
    +
    +

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

    + <%= render 'form' %> +
    diff --git a/app/views/admin/site_customization/content_blocks/index.html.erb b/app/views/admin/site_customization/content_blocks/index.html.erb index 653e3e731..e9fc664d1 100644 --- a/app/views/admin/site_customization/content_blocks/index.html.erb +++ b/app/views/admin/site_customization/content_blocks/index.html.erb @@ -2,28 +2,29 @@ Admin - <%= t("admin.menu.site_customization.content_blocks") %> <% end %> -<%= link_to t("admin.site_customization.content_blocks.index.create"), new_admin_site_customization_content_block_path, class: "button float-right margin-right" %> +<%= link_to t("admin.site_customization.content_blocks.index.create"), new_admin_site_customization_content_block_path, class: "button float-right" %> +

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

    - - - - - - - - - - <% @content_blocks.each do |content_block| %> - - - - - - <% end %> - -
    <%= t("admin.site_customization.content_blocks.content_block.name") %><%= t("admin.site_customization.content_blocks.content_block.body") %>
    <%= link_to "#{content_block.name} (#{content_block.locale})", edit_admin_site_customization_content_block_path(content_block) %><%= content_block.body %> - <%= button_to t("admin.site_customization.content_blocks.index.delete"), - admin_site_customization_content_block_path(content_block), - method: :delete, class: "button hollow alert" %> -
    + + + + + + + + + + <% @content_blocks.each do |content_block| %> + + + + + + <% end %> + +
    <%= t("admin.site_customization.content_blocks.content_block.name") %><%= t("admin.site_customization.content_blocks.content_block.body") %><%= t("admin.actions.actions") %>
    <%= link_to "#{content_block.name} (#{content_block.locale})", edit_admin_site_customization_content_block_path(content_block) %><%= content_block.body.html_safe %> + <%= button_to t("admin.site_customization.content_blocks.index.delete"), + admin_site_customization_content_block_path(content_block), + method: :delete, class: "button hollow alert" %> +
    diff --git a/app/views/admin/site_customization/content_blocks/new.html.erb b/app/views/admin/site_customization/content_blocks/new.html.erb index 75ff5f389..6a5a1e0b3 100644 --- a/app/views/admin/site_customization/content_blocks/new.html.erb +++ b/app/views/admin/site_customization/content_blocks/new.html.erb @@ -2,13 +2,11 @@ Admin - <%= t("admin.menu.site_customization.content_blocks") %> - <%= t("admin.site_customization.content_blocks.new.title") %> <% end %> -<%= link_to admin_site_customization_content_blocks_path, class: "back" do %> - - <%= t("admin.site_customization.content_blocks.new.back") %> -<% end %> +<%= back_link_to admin_site_customization_content_blocks_path %> -
    -

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

    - <%= render 'form' %> +
    +
    +

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

    + <%= render 'form' %> +
    - diff --git a/app/views/admin/site_customization/images/index.html.erb b/app/views/admin/site_customization/images/index.html.erb index b9de152d1..95b9e18a7 100644 --- a/app/views/admin/site_customization/images/index.html.erb +++ b/app/views/admin/site_customization/images/index.html.erb @@ -1,6 +1,12 @@

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

    + + + + + + <% @images.each do |image| %> diff --git a/app/views/admin/site_customization/pages/_form.html.erb b/app/views/admin/site_customization/pages/_form.html.erb index 197520631..2c0d38ba6 100644 --- a/app/views/admin/site_customization/pages/_form.html.erb +++ b/app/views/admin/site_customization/pages/_form.html.erb @@ -1,21 +1,44 @@ <%= form_for [:admin, @page], html: {class: "edit_page", data: {watch_changes: true}} do |f| %> <% if @page.errors.any? %> +
    + -
    - - - - <%= @page.errors.count %> - <%= t("admin.site_customization.pages.errors.form.error", count: @page.errors.count) %> - -
    - + + <%= @page.errors.count %> + <%= t("admin.site_customization.pages.errors.form.error", count: @page.errors.count) %> + +
    <% end %> -
    +
    +
    +
    +
    +
    +

    <%= t("admin.site_customization.pages.form.options") %>

    + <%= f.check_box :more_info_flag, class: "small" %> + <%= f.check_box :print_content_flag %> +
    +
    + <%= f.label :status %> + <% ::SiteCustomization::Page::VALID_STATUSES.each do |status| %> + <%= f.radio_button :status, status, label: false %> + <%= f.label "status_#{status}", t("admin.site_customization.pages.page.status_#{status}") %> +
    + <% end %> +
    +
    + <%= f.label :slug %> + <%= f.text_field :slug, label: false, size: 80, maxlength: 80 %> +
    +
    + +
    +
    +
    <%= f.label :title %> <%= f.text_field :title, label: false %> @@ -23,30 +46,14 @@ <%= f.label :subtitle %> <%= f.text_field :subtitle, label: false, size: 80, maxlength: 80 %> - <%= f.label :slug %> - <%= f.text_field :slug, label: false, size: 80, maxlength: 80 %> -
    <%= f.label :content %> <%= f.cktext_area :content, label: false, cols: 80, rows: 10, ckeditor: { language: I18n.locale } %>
    -
    -
    -
    -

    <%= t("admin.site_customization.pages.form.options") %>

    - <%= f.check_box :more_info_flag %> - <%= f.check_box :print_content_flag %> -
    -

    <%= f.label :status %>

    - <% ::SiteCustomization::Page::VALID_STATUSES.each do |status| %> - <%= f.radio_button :status, status, label: false %> - <%= f.label "status_#{status}", t("admin.site_customization.pages.page.status_#{status}") %> -
    - <% end %> - - <%= f.submit class: "button success" %> +
    + <%= f.submit class: "button success expanded" %> +
    -
    <% end %> diff --git a/app/views/admin/site_customization/pages/edit.html.erb b/app/views/admin/site_customization/pages/edit.html.erb index c92933cbf..9a2fc92ab 100644 --- a/app/views/admin/site_customization/pages/edit.html.erb +++ b/app/views/admin/site_customization/pages/edit.html.erb @@ -2,14 +2,13 @@ Admin - <%= t("admin.menu.site_customization.pages") %> - <%= @page.title %> <% end %> -<%= link_to admin_site_customization_pages_path, class: "back" do %> - - <%= t("admin.site_customization.pages.edit.back") %> -<% end %> +<%= back_link_to admin_site_customization_pages_path %> -<%= button_to t("admin.site_customization.pages.index.delete"), admin_site_customization_page_path(@page), method: :delete, class: "button hollow alert float-right margin-right" %> +<%= button_to t("admin.site_customization.pages.index.delete"), admin_site_customization_page_path(@page), method: :delete, class: "button hollow alert small float-right" %> -
    -

    <%= t("admin.site_customization.pages.edit.title", page_title: @page.title) %>

    - <%= render 'form' %> +
    +
    +

    <%= t("admin.site_customization.pages.edit.title", page_title: @page.title) %>

    + <%= render 'form' %> +
    diff --git a/app/views/admin/site_customization/pages/index.html.erb b/app/views/admin/site_customization/pages/index.html.erb index eef3370e6..f81631640 100644 --- a/app/views/admin/site_customization/pages/index.html.erb +++ b/app/views/admin/site_customization/pages/index.html.erb @@ -2,42 +2,45 @@ Admin - <%= t("admin.menu.site_customization.pages") %> <% end %> -<%= link_to t("admin.site_customization.pages.index.create"), new_admin_site_customization_page_path, class: "button float-right margin-right" %> +<%= link_to t("admin.site_customization.pages.index.create"), new_admin_site_customization_page_path, class: "button float-right" %>

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

    -

    <%= page_entries_info @pages %>

    +

    <%= page_entries_info @pages %>

    -
    <%= t("admin.site_customization.images.index.image") %><%= t("admin.actions.actions") %>
    - - - - - - - - - - - - <% @pages.each do |page| %> - - - - - - - - - <% end %> - -
    <%= t("admin.site_customization.pages.page.title") %><%= t("admin.site_customization.pages.page.created_at") %><%= t("admin.site_customization.pages.page.updated_at") %><%= t("admin.site_customization.pages.page.status") %>
    - <%= link_to page.title, edit_admin_site_customization_page_path(page) %> - <%= I18n.l page.created_at, format: :short %><%= I18n.l page.created_at, format: :short %><%= t("admin.site_customization.pages.page.status_#{page.status}") %> - - <%= link_to t("admin.site_customization.pages.index.see_page"), page.url %> - - - <%= link_to t("admin.site_customization.pages.index.delete"), admin_site_customization_page_path(page), method: :delete %> -
    + + + + + + + + + + + + <% @pages.each do |page| %> + + + + + + + + + <% end %> + +
    <%= t("admin.site_customization.pages.page.title") %><%= t("admin.site_customization.pages.page.created_at") %><%= t("admin.site_customization.pages.page.updated_at") %><%= t("admin.site_customization.pages.page.status") %><%= t("admin.actions.actions") %>
    + <%= link_to page.title, edit_admin_site_customization_page_path(page) %> + <%= I18n.l page.created_at, format: :short %><%= I18n.l page.created_at, format: :short %><%= t("admin.site_customization.pages.page.status_#{page.status}") %> + + <% if page.status == "published" %> + <%= link_to t("admin.site_customization.pages.index.see_page"), page.url, target: "_blank" %> + <% else %> + <%= t("admin.site_customization.pages.index.see_page") %> + <% end %> + + + <%= link_to t("admin.site_customization.pages.index.delete"), admin_site_customization_page_path(page), method: :delete, class: "delete" %> +
    - <%= paginate @pages %> +<%= paginate @pages %> diff --git a/app/views/admin/site_customization/pages/new.html.erb b/app/views/admin/site_customization/pages/new.html.erb index 43a86d108..2d555c5b8 100644 --- a/app/views/admin/site_customization/pages/new.html.erb +++ b/app/views/admin/site_customization/pages/new.html.erb @@ -2,13 +2,11 @@ Admin - <%= t("admin.menu.site_customization.pages") %> - <%= t("admin.site_customization.pages.new.title") %> <% end %> -<%= link_to admin_site_customization_pages_path, class: "back" do %> - - <%= t("admin.site_customization.pages.new.back") %> -<% end %> +<%= back_link_to admin_site_customization_pages_path %> -
    -

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

    - <%= render 'form' %> +
    +
    +

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

    + <%= render 'form' %> +
    - diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 5ae6d6f49..7b937db8b 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -679,16 +679,14 @@ en: notice: Content block deleted successfully edit: title: Editing content block - back: Back errors: form: error: Error index: create: Create new content block - delete: Delete + delete: Delete block title: Content blocks new: - back: Back title: Create new content block content_block: body: Body @@ -698,6 +696,7 @@ en: title: Custom images update: Update delete: Delete + image: Image update: notice: Image updated successfully error: Image couldn't be updated @@ -715,7 +714,6 @@ en: notice: Page deleted successfully edit: title: Editing %{page_title} - back: Back errors: form: error: Error @@ -723,11 +721,10 @@ en: options: Options index: create: Create new page - delete: Delete + delete: Delete page title: Custom Pages see_page: See page new: - back: Back title: Create new custom page page: created_at: Created at diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index f5db64135..580c46bf6 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -679,16 +679,14 @@ es: notice: Bloque borrado correctamente edit: title: Editar bloque - back: Volver errors: form: error: Error index: create: Crear nuevo bloque - delete: Borrar + delete: Borrar bloque title: Bloques new: - back: Volver title: Crear nuevo bloque content_block: body: Contenido @@ -698,6 +696,7 @@ es: title: Personalizar imágenes update: Actualizar delete: Borrar + image: Imagen update: notice: Imagen actualizada correctamente error: No se ha podido actualizar la imagen @@ -715,7 +714,6 @@ es: notice: Página eliminada correctamente edit: title: Editar %{page_title} - back: Volver errors: form: error: Error @@ -723,13 +721,13 @@ es: options: Opciones index: create: Crear nueva página - delete: Borrar + delete: Borrar página title: Páginas see_page: Ver página new: - back: Back title: Página nueva page: + actions: Acciones created_at: Creada status: Estado title: Título From 54a90bbdc9479c044b871952f3fec638b0c215e6 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 17 Apr 2017 19:21:04 +0200 Subject: [PATCH 550/613] updates texts on specs --- config/locales/admin.es.yml | 1 - spec/features/admin/site_customization/content_blocks_spec.rb | 4 ++-- spec/features/admin/site_customization/pages_spec.rb | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 580c46bf6..160b187ea 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -727,7 +727,6 @@ es: new: title: Página nueva page: - actions: Acciones created_at: Creada status: Estado title: Título diff --git a/spec/features/admin/site_customization/content_blocks_spec.rb b/spec/features/admin/site_customization/content_blocks_spec.rb index cc5dca34c..de2155737 100644 --- a/spec/features/admin/site_customization/content_blocks_spec.rb +++ b/spec/features/admin/site_customization/content_blocks_spec.rb @@ -88,7 +88,7 @@ feature "Admin custom content blocks" do expect(page).to have_content("#{block.name} (#{block.locale})") expect(page).to have_content(block.body) - click_button "Delete" + click_button "Delete block" expect(page).to_not have_content("#{block.name} (#{block.locale})") expect(page).to_not have_content(block.body) @@ -98,7 +98,7 @@ feature "Admin custom content blocks" do block = create(:site_customization_content_block) visit edit_admin_site_customization_content_block_path(block) - click_button "Delete" + click_button "Delete block" expect(page).to_not have_content("#{block.name} (#{block.locale})") expect(page).to_not have_content(block.body) diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb index 5d03638d8..3e940ea69 100644 --- a/spec/features/admin/site_customization/pages_spec.rb +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -62,7 +62,7 @@ feature "Admin custom pages" do custom_page = create(:site_customization_page, title: "An example custom page") visit edit_admin_site_customization_page_path(custom_page) - click_button "Delete" + click_button "Delete page" expect(page).to_not have_content("An example custom page") end From 68c5267a78d243dee696bab8c114cb70df42782a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 19 Apr 2017 12:10:12 +0200 Subject: [PATCH 551/613] fixes typo --- config/locales/pages.en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/pages.en.yml b/config/locales/pages.en.yml index a7b4ca43c..1fdf2bdc4 100755 --- a/config/locales/pages.en.yml +++ b/config/locales/pages.en.yml @@ -23,7 +23,7 @@ en: figcaption: '"I agree" and "I disagree" buttons to rate the debates.' proposals: title: "Proposals" - description: "Propose what you want the City Council to carry out and support proposals from other people." + description: "Propose what you want the City Council to do and support proposals from other people." feature_1: "To create a proposal you have to %{link}, in addition to support you must verify your account." feature_1_link: "sign up on %{org_name}" feature_2_html: "Proposals that get support from 1% of people will be voted on." From 3d0b7f10349e84912f4980e6ecac3bca6796ba7a Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 21 Apr 2017 16:40:16 +0200 Subject: [PATCH 552/613] prevents pages indexation on robots.txt --- public/robots.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/public/robots.txt b/public/robots.txt index 3c9c7c01f..93780f8d1 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -3,3 +3,10 @@ # To ban all spiders from the entire site uncomment the next two lines: # User-agent: * # Disallow: / + +Disallow: /users/ +Disallow: /comments/ + +Disallow: /*?*locale +Disallow: /*?*order +Disallow: /*?*search From 8b42d57e18ee8a1c77422e154d7cd059bea9b3ff Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 21 Apr 2017 16:59:11 +0200 Subject: [PATCH 553/613] adds rel nofollow on links --- app/views/devise/menu/_login_items.html.erb | 17 +++++++++++------ app/views/layouts/_footer.html.erb | 14 +++++++------- app/views/shared/_top_links.html.erb | 3 +++ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/app/views/devise/menu/_login_items.html.erb b/app/views/devise/menu/_login_items.html.erb index b7db4a22c..5d493131d 100644 --- a/app/views/devise/menu/_login_items.html.erb +++ b/app/views/devise/menu/_login_items.html.erb @@ -1,6 +1,6 @@ <% if user_signed_in? %>
  • - <%= link_to notifications_path, class: "notifications" do %> + <%= link_to notifications_path, rel: "nofollow", class: "notifications" do %> <%= t("layouts.header.notifications") %> <% if current_user.notifications_count > 0 %> @@ -12,19 +12,24 @@ <% end %>
  • - <%= link_to t("layouts.header.my_activity_link"), user_path(current_user) %> + <%= link_to t("layouts.header.my_activity_link"), + user_path(current_user), rel: "nofollow" %>
  • - <%= link_to t("layouts.header.my_account_link"), account_path %> + <%= link_to t("layouts.header.my_account_link"), + account_path, rel: "nofollow" %>
  • - <%= link_to t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete %> + <%= link_to t("devise_views.menu.login_items.logout"), + destroy_user_session_path, rel: "nofollow", method: :delete %>
  • <% else %>
  • - <%= link_to t("devise_views.menu.login_items.login"), new_user_session_path %> + <%= link_to t("devise_views.menu.login_items.login"), + new_user_session_path, rel: "nofollow" %>
  • - <%= link_to t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button" %> + <%= link_to t("devise_views.menu.login_items.signup"), + new_user_registration_path, rel: "nofollow", class: "button" %>
  • <% end %> diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 0bce1cd67..35e7d63a0 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -25,14 +25,14 @@

    - <%= link_to t("layouts.footer.transparency_title"), setting['transparency_url'].presence || t("layouts.footer.transparency_url") %> + <%= link_to t("layouts.footer.transparency_title"), setting['transparency_url'].presence || t("layouts.footer.transparency_url"), rel: "nofollow" %>

    <%= t("layouts.footer.transparency_text") %>

    - <%= link_to t("layouts.footer.open_data_title"), setting['opendata_url'].presence || t("layouts.header.external_link_opendata_url") %> + <%= link_to t("layouts.footer.open_data_title"), setting['opendata_url'].presence || t("layouts.header.external_link_opendata_url"), rel: "nofollow" %>

    <%= t("layouts.footer.open_data_text") %>

    @@ -54,7 +54,7 @@
      <% if setting['twitter_handle'] %>
    • - <%= link_to "https://twitter.com/#{setting['twitter_handle']}", target: "_blank", title: t("social.twitter") + t('shared.target_blank_html') do %> + <%= link_to "https://twitter.com/#{setting['twitter_handle']}", target: "_blank", title: t("social.twitter") + t('shared.target_blank_html'), rel: "nofollow" do %> <%= t("social.twitter") %> <% end %> @@ -62,7 +62,7 @@ <% end %> <% if setting['facebook_handle'] %>
    • - <%= link_to "https://www.facebook.com/#{setting['facebook_handle']}/", target: "_blank", title: t("social.facebook") + t('shared.target_blank_html') do %> + <%= link_to "https://www.facebook.com/#{setting['facebook_handle']}/", target: "_blank", title: t("social.facebook") + t('shared.target_blank_html'), rel: "nofollow" do %> <%= t("social.facebook") %> <% end %> @@ -70,7 +70,7 @@ <% end %> <% if setting['blog_url'] %>
    • - <%= link_to setting['blog_url'], target: "_blank", title: t("social.blog") + t('shared.target_blank_html') do %> + <%= link_to setting['blog_url'], target: "_blank", title: t("social.blog") + t('shared.target_blank_html'), rel: "nofollow" do %> <%= t("social.blog") %> <% end %> @@ -78,7 +78,7 @@ <% end %> <% if setting['youtube_handle'] %>
    • - <%= link_to "https://www.youtube.com/#{setting['youtube_handle']}", target: "_blank", title: t("social.youtube") + t('shared.target_blank_html') do %> + <%= link_to "https://www.youtube.com/#{setting['youtube_handle']}", target: "_blank", title: t("social.youtube") + t('shared.target_blank_html'), rel: "nofollow" do %> <%= t("social.youtube") %> <% end %> @@ -86,7 +86,7 @@ <% end %> <% if setting['telegram_handle'] %>
    • - <%= link_to "https://www.telegram.me/#{setting['telegram_handle']}", target: "_blank", title: t("social.telegram") + t('shared.target_blank_html') do %> + <%= link_to "https://www.telegram.me/#{setting['telegram_handle']}", target: "_blank", title: t("social.telegram") + t('shared.target_blank_html'), rel: "nofollow" do %> <%= t("social.telegram") %> <% end %> diff --git a/app/views/shared/_top_links.html.erb b/app/views/shared/_top_links.html.erb index 8a71130d6..ae77cb1c2 100644 --- a/app/views/shared/_top_links.html.erb +++ b/app/views/shared/_top_links.html.erb @@ -3,12 +3,14 @@ <%= link_to t("layouts.header.external_link_transparency"), setting['transparency_url'].presence || t("layouts.header.external_link_transparency_url"), target: "_blank", + rel: "nofollow", title: t('shared.target_blank_html') %>
    • <%= link_to t("layouts.header.external_link_opendata"), setting['opendata_url'].presence || t("layouts.header.external_link_opendata_url"), target: "_blank", + rel: "nofollow", title: t('shared.target_blank_html') %>
    • @@ -17,6 +19,7 @@ <%= link_to t("layouts.header.external_link_blog"), setting['blog_url'], target: "_blank", + rel: "nofollow", title: t('shared.target_blank_html') %> <% end %> From 4a06e34aa6978989f714bd5ad519e0c4ace13dda Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 21 Apr 2017 16:59:28 +0200 Subject: [PATCH 554/613] fixes old faq page path --- app/views/layouts/_footer.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 35e7d63a0..eedd0ac89 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -11,7 +11,7 @@ consul: link_to(t("layouts.footer.consul"), t("layouts.footer.consul_url"), target: "blank")).html_safe %> <%= t("layouts.footer.contact_us") %> - <%= link_to t("layouts.footer.faq"), page_path('faq') %> + <%= link_to t("layouts.footer.faq"), faq_path %>

    From 05c366e2fff98f04a3f8ea303f33696e1451ca87 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 21 Apr 2017 17:10:11 +0200 Subject: [PATCH 555/613] removes headings on footer --- app/assets/stylesheets/layout.scss | 8 ++------ app/views/layouts/_footer.html.erb | 12 +++--------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 94d403528..7c204bced 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -587,12 +587,8 @@ footer { padding-left: 0; } - h2 a { - border-bottom: 1px solid $text-light; - display: block; - font-size: rem-calc(24); - line-height: rem-calc(31); - padding-bottom: $line-height/4; + a.title { + font-weight: bold; text-decoration: none; } } diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index eedd0ac89..2e2f5c063 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -17,23 +17,17 @@ From f7020618da26ef20fd35301b5d271d4e9a1772f7 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 21 Apr 2017 20:08:46 +0200 Subject: [PATCH 556/613] adds pages, budgets and polls to sitemap.rb --- config/sitemap.rb | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/config/sitemap.rb b/config/sitemap.rb index 11ec9fb09..e5537dd9f 100644 --- a/config/sitemap.rb +++ b/config/sitemap.rb @@ -15,7 +15,11 @@ SitemapGenerator::Sitemap.create do add page_name if page_name.present? end - add "help_translate" + add more_info_path + add how_to_use_path + add faq_path + add participation_facts_path + add participation_world_path add debates_path, priority: 0.7, changefreq: "daily" Debate.find_each do |debate| @@ -27,10 +31,18 @@ SitemapGenerator::Sitemap.create do add proposal_path(proposal), lastmod: proposal.updated_at end - add proposal_ballots_path - add spending_proposals_path, priority: 0.7, changefreq: "daily" SpendingProposal.find_each do |spending_proposal| add spending_proposal_path(spending_proposal), lastmod: spending_proposal.updated_at end + + add budgets_path, priority: 0.7, changefreq: "daily" + Budget.find_each do |budget| + add budget_path(budget), lastmod: budget.updated_at + end + + add polls_path, priority: 0.7, changefreq: "daily" + Poll.find_each do |poll| + add poll_path(poll), lastmod: poll.starts_at + end end From d8bc2ef67d2ac4d275bb2e1607b52e9482f3e3cd Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 24 Apr 2017 12:52:45 +0200 Subject: [PATCH 557/613] changes name of budgets menu --- config/locales/es.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/es.yml b/config/locales/es.yml index 7d942a1e6..bcf6e1b0f 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -215,7 +215,7 @@ es: proposals: Propuestas poll_questions: Votaciones see_all: Ver propuestas - budgets: Presupuestos ciudadanos + budgets: Presupuestos participativos spending_proposals: "Propuestas de inversión" legislation: help: From 13c5eb981216e6f6765d001846cffc3d4a2d7171 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 24 Apr 2017 13:03:09 +0200 Subject: [PATCH 558/613] improves valuation budget investment form --- .../valuation/budget_investments/edit.html.erb | 14 +++++++------- config/locales/valuation.en.yml | 2 +- config/locales/valuation.es.yml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/valuation/budget_investments/edit.html.erb b/app/views/valuation/budget_investments/edit.html.erb index 16dc3b59d..fa748b098 100644 --- a/app/views/valuation/budget_investments/edit.html.erb +++ b/app/views/valuation/budget_investments/edit.html.erb @@ -8,7 +8,7 @@ <%= form_for(@investment, url: valuate_valuation_budget_budget_investment_path(@budget, @investment), html: {id: "valuation_budget_investment_edit_form"}) do |f| %> <%= render 'shared/errors', resource: @investment %>
    -
    +
    <%= t('valuation.budget_investments.edit.feasibility') %>
    @@ -38,7 +38,7 @@
    -
    +
    <%= f.label :unfeasibility_explanation, t("valuation.budget_investments.edit.feasible_explanation_html") %> <%= f.text_area :unfeasibility_explanation, label: false, rows: 3 %>
    @@ -49,26 +49,26 @@
    -
    +
    <%= f.label :price, "#{t('valuation.budget_investments.edit.price_html', currency: @budget.currency_symbol)}" %> <%= f.number_field :price, label: false, max: 1000000000000000 %>
    -
    +
    <%= f.label :price_first_year, "#{t('valuation.budget_investments.edit.price_first_year_html', currency: @budget.currency_symbol)}" %> <%= f.number_field :price_first_year, label: false, max: 1000000000000000 %>
    -
    +
    <%= f.label :price_explanation, t("valuation.budget_investments.edit.price_explanation_html") %> <%= f.text_area :price_explanation, label: false, rows: 3 %>
    -
    +
    <%= f.label :duration, t("valuation.budget_investments.edit.duration_html") %> <%= f.text_field :duration, label: false %>
    @@ -86,7 +86,7 @@
    -
    +
    <%= f.label :internal_comments, t("valuation.budget_investments.edit.internal_comments_html") %> <%= f.text_area :internal_comments, label: false, rows: 3 %>
    diff --git a/config/locales/valuation.en.yml b/config/locales/valuation.en.yml index 56cf38f4c..ecfbc113f 100644 --- a/config/locales/valuation.en.yml +++ b/config/locales/valuation.en.yml @@ -61,7 +61,7 @@ en: edit: dossier: Dossier price_html: "Price (%{currency})" - price_first_year_html: "Cost during the first year (%{currency})" + price_first_year_html: "Cost during the first year (%{currency}) (optional, data not public)" price_explanation_html: Price explanation feasibility: Feasibility feasible: Feasible diff --git a/config/locales/valuation.es.yml b/config/locales/valuation.es.yml index e45b57e73..b3a5c32ca 100644 --- a/config/locales/valuation.es.yml +++ b/config/locales/valuation.es.yml @@ -61,7 +61,7 @@ es: edit: dossier: Informe price_html: "Coste (%{currency}) (dato público)" - price_first_year_html: "Coste en el primer año (%{currency}) (opcional, privado)" + price_first_year_html: "Coste en el primer año (%{currency}) (opcional, dato no público)" price_explanation_html: "Informe de coste (opcional, dato público)" feasibility: Viabilidad feasible: Viable From 26ce2a1ae2fdfaef7089734d840377c6f273bb6f Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 24 Apr 2017 13:12:33 +0200 Subject: [PATCH 559/613] fixes admin budgets group table --- app/views/admin/budgets/_group.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/budgets/_group.html.erb b/app/views/admin/budgets/_group.html.erb index e90bd4905..6193fe287 100644 --- a/app/views/admin/budgets/_group.html.erb +++ b/app/views/admin/budgets/_group.html.erb @@ -1,7 +1,7 @@ - From e7167855c4da7358fbd3fe585b41a536c152e116 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 24 Apr 2017 13:12:44 +0200 Subject: [PATCH 560/613] improves admin budgets edit page --- app/views/admin/budgets/edit.html.erb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/views/admin/budgets/edit.html.erb b/app/views/admin/budgets/edit.html.erb index 94da65a31..6c54cc75b 100644 --- a/app/views/admin/budgets/edit.html.erb +++ b/app/views/admin/budgets/edit.html.erb @@ -1,9 +1,5 @@ <%= back_link_to admin_budgets_path %> -
    -
    -

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

    +

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

    - <%= render '/admin/budgets/form' %> -
    -
    +<%= render '/admin/budgets/form' %> From 45af9ce5aa3ea252eab22df6c6016a7c287108df Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Tue, 25 Apr 2017 16:46:20 +0200 Subject: [PATCH 561/613] adds budget investments numbers and chart on admin stats --- app/controllers/admin/api/stats_controller.rb | 11 +++-- app/controllers/admin/stats_controller.rb | 2 + app/helpers/stats_helper.rb | 7 ++++ app/views/admin/stats/show.html.erb | 40 ++++++++++++++----- config/locales/admin.en.yml | 3 ++ config/locales/admin.es.yml | 3 ++ .../admin/api/stats_controller_spec.rb | 19 +++++++++ 7 files changed, 72 insertions(+), 13 deletions(-) diff --git a/app/controllers/admin/api/stats_controller.rb b/app/controllers/admin/api/stats_controller.rb index e58d9d754..fe8c72cdd 100644 --- a/app/controllers/admin/api/stats_controller.rb +++ b/app/controllers/admin/api/stats_controller.rb @@ -1,9 +1,10 @@ class Admin::Api::StatsController < Admin::Api::BaseController def show - unless params[:events].present? || - params[:visits].present? || - params[:spending_proposals].present? + unless params[:events].present? || + params[:visits].present? || + params[:spending_proposals].present? || + params[:budget_investments].present? return render json: {}, status: :bad_request end @@ -24,6 +25,10 @@ class Admin::Api::StatsController < Admin::Api::BaseController ds.add "Spending proposals", SpendingProposal.group_by_day(:created_at).count end + if params[:budget_investments].present? + ds.add "Budget Investments", Budget::Investment.group_by_day(:created_at).count + end + render json: ds.build end end diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb index 3624174a5..6a2021592 100644 --- a/app/controllers/admin/stats_controller.rb +++ b/app/controllers/admin/stats_controller.rb @@ -21,6 +21,8 @@ class Admin::StatsController < Admin::BaseController @user_ids_who_voted_proposals = ActsAsVotable::Vote.where(votable_type: 'Proposal').distinct.count(:voter_id) @user_ids_who_didnt_vote_proposals = @verified_users - @user_ids_who_voted_proposals @spending_proposals = SpendingProposal.count + @budgets = Budget.where.not(phase: 'finished').count + @investments = Budget.where.not(phase: 'finished').collect(&:investments).flatten.count end def proposal_notifications diff --git a/app/helpers/stats_helper.rb b/app/helpers/stats_helper.rb index e481ef7e1..d8eff0ac2 100644 --- a/app/helpers/stats_helper.rb +++ b/app/helpers/stats_helper.rb @@ -21,4 +21,11 @@ module StatsHelper content_tag :div, "", opt end + def budget_investments_chart_tag(opt={}) + events = events.join(',') if events.is_a? Array + opt[:data] ||= {} + opt[:data][:graph] = admin_api_stats_path(budget_investments: true) + content_tag :div, "", opt + end + end diff --git a/app/views/admin/stats/show.html.erb b/app/views/admin/stats/show.html.erb index cd83201a4..a37ff62bd 100644 --- a/app/views/admin/stats/show.html.erb +++ b/app/views/admin/stats/show.html.erb @@ -36,6 +36,16 @@ <%= t "admin.stats.show.summary.comments" %>
    <%= number_with_delimiter(@comments) %>

    + <% if feature?(:polls) %> +

    + <%= t "admin.stats.show.summary.budgets" %>
    + <%= number_with_delimiter(@budgets) %> +

    + + <% end %>
    @@ -96,12 +106,14 @@

    -
    - -
    + <% if feature?(:spending_proposals) %> +
    + +
    + <% end %>
    @@ -116,11 +128,19 @@ <% end %>
    -
    -

    <%= t "admin.stats.show.spending_proposals_title" %>

    - <%= spending_proposals_chart_tag id: "spending_proposals" %> -
    + <% if feature?(:spending_proposals) %> +
    +

    <%= t "admin.stats.show.spending_proposals_title" %>

    + <%= spending_proposals_chart_tag id: "spending_proposals" %> +
    + <% end %> + <% if feature?(:polls) %> +
    +

    <%= t "admin.stats.show.budgets_title" %>

    + <%= budget_investments_chart_tag id: "budget_investments" %> +
    + <% end %> diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index 7b937db8b..f99ef1780 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -612,6 +612,8 @@ en: debates: Debates proposal_votes: Proposal votes proposals: Proposals + budgets: Open budgets + budget_investments: Investment projects spending_proposals: Spending Proposals unverified_users: Unverified users user_level_three: Level three users @@ -622,6 +624,7 @@ en: visits: Visits votes: Total votes spending_proposals_title: Spending Proposals + budgets_title: Participatory budgeting visits_title: Visits direct_messages: Direct messages proposal_notifications: Proposal notifications diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 160b187ea..817576494 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -612,6 +612,8 @@ es: debates: Debates proposal_votes: Votos en propuestas proposals: Propuestas + budgets: Presupuestos abiertos + budget_investments: Propuestas de inversión spending_proposals: Propuestas de inversión unverified_users: Usuarios sin verificar user_level_three: Usuarios de nivel tres @@ -622,6 +624,7 @@ es: visits: Visitas votes: Votos spending_proposals_title: Propuestas de inversión + budgets_title: Presupuestos participativos visits_title: Visitas direct_messages: Mensajes directos proposal_notifications: Notificaciones de propuestas diff --git a/spec/controllers/admin/api/stats_controller_spec.rb b/spec/controllers/admin/api/stats_controller_spec.rb index e28bd3591..7ba63ffb3 100644 --- a/spec/controllers/admin/api/stats_controller_spec.rb +++ b/spec/controllers/admin/api/stats_controller_spec.rb @@ -91,5 +91,24 @@ describe Admin::Api::StatsController do expect(data).to eq "x"=>["2015-01-01", "2015-01-02"], "Foo"=>[1, 2], "Visits"=>[2, 1] end end + + context 'budget investments present' do + it 'should return budget investments formated for working with c3.js' do + time_1 = DateTime.parse("2017-04-01") + time_2 = DateTime.parse("2017-04-02") + + budget_investment1 = create(:budget_investment, budget: @budget, created_at: time_1) + budget_investment2 = create(:budget_investment, budget: @budget, created_at: time_2) + budget_investment3 = create(:budget_investment, budget: @budget, created_at: time_2) + + sign_in user + get :show, budget_investments: true + + expect(response).to be_ok + + data = JSON.parse(response.body) + expect(data).to eq "x"=>["2017-04-01", "2017-04-02"], "Budget Investments"=>[1, 2] + end + end end end From 96a54397ab126d94414053149441141d638a937d Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 26 Apr 2017 12:30:37 +0200 Subject: [PATCH 562/613] fixes typo on pages.en.yml --- config/locales/pages.en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/pages.en.yml b/config/locales/pages.en.yml index 1fdf2bdc4..ab086bdbd 100755 --- a/config/locales/pages.en.yml +++ b/config/locales/pages.en.yml @@ -37,7 +37,7 @@ en: feature_1_link: "sign up on %{org_name}" feature_2_html: "The first is the submit phase of investment projects." feature_3_html: "Then there is a support phase to prioritize the most interesting, the most supported are evaluated by the City to see if they are viable and how much they are worth." - feature_4_html: "At the end there is a vote phase where it is decided on which part of the budget is spent." + feature_4_html: "At the end there is a vote phase and you decide which of the approved projects to spend the budget on." image_alt: "Different phases of a participatory budget" figcaption_html: '"Support phase" and "Voting" phase of participatory budgets.' polls: From f15133708065cd7e90e7cce8bb745d507ae1c7e6 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 26 Apr 2017 13:12:20 +0200 Subject: [PATCH 563/613] corrects feature polls to budgets --- app/views/admin/stats/show.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/stats/show.html.erb b/app/views/admin/stats/show.html.erb index a37ff62bd..137f3ce81 100644 --- a/app/views/admin/stats/show.html.erb +++ b/app/views/admin/stats/show.html.erb @@ -36,7 +36,7 @@ <%= t "admin.stats.show.summary.comments" %>
    <%= number_with_delimiter(@comments) %>

    - <% if feature?(:polls) %> + <% if feature?(:budgets) %>

    <%= t "admin.stats.show.summary.budgets" %>
    <%= number_with_delimiter(@budgets) %> @@ -135,7 +135,7 @@ <% end %> - <% if feature?(:polls) %> + <% if feature?(:budgets) %>

    <%= t "admin.stats.show.budgets_title" %>

    <%= budget_investments_chart_tag id: "budget_investments" %> From 60d08ab5656687d254cec1b02f6d27eecd7ba3ad Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 26 Apr 2017 13:12:55 +0200 Subject: [PATCH 564/613] improves query on admin stats controller --- app/controllers/admin/stats_controller.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb index 6a2021592..9989da796 100644 --- a/app/controllers/admin/stats_controller.rb +++ b/app/controllers/admin/stats_controller.rb @@ -21,8 +21,9 @@ class Admin::StatsController < Admin::BaseController @user_ids_who_voted_proposals = ActsAsVotable::Vote.where(votable_type: 'Proposal').distinct.count(:voter_id) @user_ids_who_didnt_vote_proposals = @verified_users - @user_ids_who_voted_proposals @spending_proposals = SpendingProposal.count - @budgets = Budget.where.not(phase: 'finished').count - @investments = Budget.where.not(phase: 'finished').collect(&:investments).flatten.count + budgets_ids = Budget.where.not(phase: 'finished').pluck(:id) + @budgets = budgets_ids.size + @investments = Budget::Investment.where(budget_id: budgets_ids).count end def proposal_notifications From 078d8da30d519af6213d82ef3ad6b48ba9923a8c Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Thu, 27 Apr 2017 16:37:41 +0200 Subject: [PATCH 565/613] changes page paths on sitemap.rb --- config/sitemap.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/config/sitemap.rb b/config/sitemap.rb index e5537dd9f..76ba7cec9 100644 --- a/config/sitemap.rb +++ b/config/sitemap.rb @@ -9,10 +9,13 @@ SitemapGenerator::Sitemap.default_host = Setting["url"] # sitemap generator SitemapGenerator::Sitemap.create do - pages = Dir.entries(File.join(Rails.root,"app","views","pages")) + pages = ["accessibility", + "census_terms", + "conditions", + "general_terms", + "privacy"] pages.each do |page| - page_name = page.split(".").first - add page_name if page_name.present? + add page_path(id: page) end add more_info_path From 86545177434292cf723e912620b9ca89f66fdbf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Thu, 27 Apr 2017 17:04:25 +0200 Subject: [PATCH 566/613] changes budget name max length --- app/models/budget.rb | 4 ++++ db/migrate/20170427145845_change_budget_name.rb | 9 +++++++++ db/schema.rb | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20170427145845_change_budget_name.rb diff --git a/app/models/budget.rb b/app/models/budget.rb index 2741ac014..c4f953915 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -35,6 +35,10 @@ class Budget < ActiveRecord::Base 2000 end + def self.title_max_length + 80 + end + def accepting? phase == "accepting" end diff --git a/db/migrate/20170427145845_change_budget_name.rb b/db/migrate/20170427145845_change_budget_name.rb new file mode 100644 index 000000000..cbf5e12db --- /dev/null +++ b/db/migrate/20170427145845_change_budget_name.rb @@ -0,0 +1,9 @@ +class ChangeBudgetName < ActiveRecord::Migration + def up + change_column :budgets, :name, :string, limit: 80 + end + + def down + change_column :budgets, :name, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index d54a8f506..a8b496dee 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: 20170324101716) do +ActiveRecord::Schema.define(version: 20170427145845) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -161,7 +161,7 @@ ActiveRecord::Schema.define(version: 20170324101716) do add_index "budget_valuator_assignments", ["investment_id"], name: "index_budget_valuator_assignments_on_investment_id", using: :btree create_table "budgets", force: :cascade do |t| - t.string "name", limit: 30 + t.string "name", limit: 80 t.string "currency_symbol", limit: 10 t.string "phase", limit: 40, default: "accepting" t.datetime "created_at", null: false From 15a9198b0f5a0a97db8d64c9c992ef25f8151a40 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 28 Apr 2017 11:47:34 +0200 Subject: [PATCH 567/613] fixes telegram icon and show it only on mobile size --- app/assets/stylesheets/layout.scss | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 7c204bced..b1aa65c90 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1371,6 +1371,13 @@ table { } } +@include breakpoint(medium) { + + .button.button-telegram, .ssb-telegram { + display: none !important; + } +} + .social { a { @@ -1471,7 +1478,7 @@ table { width: $line-height*2; &:before { - content: "A"; + content: "1"; font-family: "icons" !important; font-size: rem-calc(24); left: 50%; From 2e649d78ff1374cf9894fb48c4ef52eaba61daf7 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 28 Apr 2017 12:20:19 +0200 Subject: [PATCH 568/613] fixes geozone tag style on proposals show --- app/assets/stylesheets/admin.scss | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index fac6d35ed..e864d9781 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -497,18 +497,21 @@ table.investment-projects-summary { } } -.geozone { - background: #ececec; - border-radius: rem-calc(6); - color: $text; - display: inline-block; - font-size: $small-font-size; - margin-bottom: $line-height/3; - padding: $line-height/4 $line-height/3; - text-decoration: none; +body.admin { - &:hover { - background: #e0e0e0; + .geozone { + background: #ececec; + border-radius: rem-calc(6); + color: $text; + display: inline-block; + font-size: $small-font-size; + margin-bottom: $line-height/3; + padding: $line-height/4 $line-height/3; + text-decoration: none; + + &:hover { + background: #e0e0e0; + } } } From 80279ca638b9edf7ba23d19ee9385806b7f379c7 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 28 Apr 2017 12:44:38 +0200 Subject: [PATCH 569/613] improves admin banners index page --- app/views/admin/banners/index.html.erb | 72 +++++++++++++++----------- config/locales/admin.en.yml | 1 + config/locales/admin.es.yml | 1 + 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/app/views/admin/banners/index.html.erb b/app/views/admin/banners/index.html.erb index db58c1303..11f2ef6ab 100644 --- a/app/views/admin/banners/index.html.erb +++ b/app/views/admin/banners/index.html.erb @@ -7,36 +7,48 @@

    <%= page_entries_info @banners %>

    -
    + <%= group.name %> <%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %>
    - <% @banners.each do |banner| %> - - + + + + + + + + +
    - - <%= t("admin.banners.banner.post_started_at")%> <%= banner.post_started_at %> -  |  - <%= t("admin.banners.banner.post_ended_at")%> <%= banner.post_ended_at%> - - -
    -
    - <%= link_to banner.target_url do %> -

    <%= banner.title %>

    -

    <%= banner.description %>

    - <% end %> +<% @banners.each do |banner| %> + + + + + + + + + + + + + - - - - <% end %> -
    <%= t("admin.banners.banner.post_started_at")%><%= t("admin.banners.banner.post_ended_at")%><%= t("admin.actions.actions")%>
    <%= banner.post_started_at %><%= banner.post_ended_at %> +
    + <%= link_to t("admin.banners.index.edit"), edit_admin_banner_path(banner), + class: 'button hollow expanded' %>
    - -
    - <%= link_to t("admin.banners.index.edit"), edit_admin_banner_path(banner), - class: 'edit-banner button hollow' %> - - <%= link_to t("admin.banners.index.delete"), admin_banner_path(banner), - method: :delete, - class: 'button hollow alert' %> -
    +
    + <%= link_to t("admin.banners.index.delete"), admin_banner_path(banner), + method: :delete, + class: 'button hollow alert expanded' %> +
    +
    <%= t("admin.banners.index.preview") %>
    +
    +
    + <%= link_to banner.target_url do %> +

    <%= banner.title %>

    +

    <%= banner.description %>

    + <% end %> +
    +
    +
    +<% end %> <%= paginate @banners %> \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index f99ef1780..f6b796b1c 100755 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -24,6 +24,7 @@ en: all: All with_active: Active with_inactive: Inactive + preview: Preview banner: title: Title description: Description diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index 817576494..951b34a2b 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -24,6 +24,7 @@ es: all: Todos with_active: Activos with_inactive: Inactivos + preview: Vista previa banner: title: Título description: Descripción From 73e46bf3f1bd4699f7846e1a858d0f91198d582c Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 28 Apr 2017 13:04:23 +0200 Subject: [PATCH 570/613] removes old back links --- app/views/admin/banners/edit.html.erb | 5 +---- app/views/admin/banners/new.html.erb | 5 +---- config/locales/admin.en.yml | 2 -- config/locales/admin.es.yml | 2 -- 4 files changed, 2 insertions(+), 12 deletions(-) diff --git a/app/views/admin/banners/edit.html.erb b/app/views/admin/banners/edit.html.erb index 9f2ad0ac0..17cb11405 100644 --- a/app/views/admin/banners/edit.html.erb +++ b/app/views/admin/banners/edit.html.erb @@ -1,10 +1,7 @@
    diff --git a/app/views/debates/show.html.erb b/app/views/debates/show.html.erb index 64eafc0ae..1a74a592e 100644 --- a/app/views/debates/show.html.erb +++ b/app/views/debates/show.html.erb @@ -52,12 +52,11 @@

    <%= t("debates.show.share") %>

    diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 80b2d25a9..c2718584f 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -131,12 +131,11 @@

    <%= t("proposals.show.share") %>

    diff --git a/app/views/spending_proposals/show.html.erb b/app/views/spending_proposals/show.html.erb index 4c5a041d3..808ce9e4b 100644 --- a/app/views/spending_proposals/show.html.erb +++ b/app/views/spending_proposals/show.html.erb @@ -44,12 +44,11 @@

    <%= t("spending_proposals.show.share") %>

    From 551501c1483351922f501ae1fc09cd16cb2995cd Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Wed, 3 May 2017 18:08:09 +0200 Subject: [PATCH 581/613] replaces   to %20 on whatsapp links href --- app/views/budgets/investments/_investment_show.html.erb | 2 +- app/views/debates/show.html.erb | 2 +- app/views/proposals/show.html.erb | 2 +- app/views/spending_proposals/show.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index 85ccb9da2..e0822145b 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -102,7 +102,7 @@

    <%= t("budgets.investments.show.share") %>


    <% end %> + <% if investment.should_show_price? %> + +

    <%= t("budgets.investments.show.price") %>

    +
    +

    + <%= investment.formatted_price %> +

    +
    + <% end %>

    <%= t("budgets.investments.show.share") %>

    +<% elsif params[:unselected] %> +
    +
    +

    <%= t("budgets.groups.show.unselected_title") %>

    +
    +
    <% end %> -
    +
    <% @group.headings.each_slice(7) do |slice| %> @@ -25,7 +31,8 @@ class="<%= css_for_ballot_heading(heading) %>"> <%= link_to heading.name, budget_investments_path(heading_id: heading.id, - unfeasible: params[:unfeasible]), + unfeasible: params[:unfeasible], + unselected: params[:unselected]), data: { no_turbolink: true } %>
    <% end %> @@ -40,10 +47,19 @@
    <% if params[:unfeasible].blank? %> -
    +
    <%= link_to t("budgets.groups.show.unfeasible"), budget_path(@budget, unfeasible: 1) %>
    <% end %> + +<% if params[:unselected].blank? %> +
    +
    + <%= link_to t("budgets.groups.show.unselected"), + budget_path(@budget, unselected: 1) %> +
    +
    +<% end %> diff --git a/app/views/budgets/show.html.erb b/app/views/budgets/show.html.erb index e49cd4252..d6a571b46 100644 --- a/app/views/budgets/show.html.erb +++ b/app/views/budgets/show.html.erb @@ -35,10 +35,12 @@
    -
    +
    <% if params[:unfeasible] %>

    <%= t("budgets.show.unfeasible_title") %>

    + <% elsif params[:unselected] %> +

    <%= t("budgets.show.unselected_title") %>

    <% end %> @@ -52,12 +54,14 @@ <%= link_to group.name, budget_investments_path(@budget, heading_id: group.headings.first.id, - unfeasible: params[:unfeasible]), + unfeasible: params[:unfeasible], + unselected: params[:unselected]), data: { no_turbolink: true } %> <% else %> <%= link_to group.name, budget_group_path(@budget, group, - unfeasible: params[:unfeasible]) %> + unfeasible: params[:unfeasible], + unselected: params[:unselected]) %> <% end %>
    @@ -69,10 +73,19 @@ <% unless params[:unfeasible] %> -
    +
    <%= link_to t("budgets.show.unfeasible"), budget_path(@budget, unfeasible: 1) %>
    <% end %> + +<% unless params[:unselected] %> +
    +
    + <%= link_to t("budgets.show.unselected"), + budget_path(@budget, unselected: 1) %> +
    +
    +<% end %> diff --git a/config/locales/budgets.en.yml b/config/locales/budgets.en.yml index 2774dcfbd..49d1558cf 100644 --- a/config/locales/budgets.en.yml +++ b/config/locales/budgets.en.yml @@ -24,6 +24,8 @@ en: title: Select an option unfeasible_title: Unfeasible investments unfeasible: See unfeasible investments + unselected_title: Investments not selected for balloting phase + unselected: See investments not selected for balloting phase phase: accepting: Accepting projects reviewing: Reviewing projects @@ -107,4 +109,6 @@ en: group: Group phase: Actual phase unfeasible_title: Unfeasible investments - unfeasible: See unfeasible investments \ No newline at end of file + unfeasible: See unfeasible investments + unselected_title: Investments not selected for balloting phase + unselected: See investments not selected for balloting phase \ No newline at end of file diff --git a/config/locales/budgets.es.yml b/config/locales/budgets.es.yml index 84d10228a..98ef4ad4e 100644 --- a/config/locales/budgets.es.yml +++ b/config/locales/budgets.es.yml @@ -24,6 +24,8 @@ es: title: Selecciona una opción unfeasible_title: Propuestas inviables unfeasible: Ver propuestas inviables + unselected_title: Propuestas que no pasan a la votación final + unselected: Ver las propuestas que no pasan a la votación final phase: accepting: Presentación de proyectos reviewing: Revisión interna de proyectos @@ -108,3 +110,5 @@ es: phase: Fase actual unfeasible_title: Propuestas inviables unfeasible: Ver las propuestas inviables + unselected_title: Propuestas que no pasan a la votación final + unselected: Ver las propuestas que no pasan a la votación final \ No newline at end of file From 5727969eac282ecfb07631488aa612441db35574 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Fri, 5 May 2017 20:01:32 +0200 Subject: [PATCH 595/613] adds specs for unselected budget investments --- app/models/budget/investment.rb | 2 +- spec/features/budgets/investments_spec.rb | 47 +++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index e8fec254f..0b4470383 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -239,7 +239,7 @@ class Budget if budget.balloting? && params[:unfeasible].blank? && params[:unselected].blank? investments = investments.selected - elsif budget.balloting? && params[:unfeasible].blank? + elsif budget.balloting? && params[:unfeasible].blank? && params[:unselected].present? investments = investments.feasible.unselected else investments = params[:unfeasible].present? ? investments.unfeasible : investments.not_unfeasible diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 8a817a805..69d995311 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -602,5 +602,52 @@ feature 'Budget Investments' do end end + scenario 'Show unselected budget investments' do + investment1 = create(:budget_investment, :feasible, heading: heading, valuation_finished: true) + investment2 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) + investment3 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) + investment4 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) + + visit budget_investments_path(budget_id: budget.id, heading_id: heading.id, unselected: 1) + + within("#budget-investments") do + expect(page).to have_css('.budget-investment', count: 1) + + expect(page).to have_content(investment1.title) + expect(page).to_not have_content(investment2.title) + expect(page).to_not have_content(investment3.title) + expect(page).to_not have_content(investment4.title) + end + end + + scenario "Shows unselected link for group with one heading" do + group = create(:budget_group, name: 'All City', budget: budget) + heading = create(:budget_heading, name: "Madrid", group: group) + + visit budget_path(budget) + click_link 'See investments not selected for balloting phase' + + click_link "All City" + + expected_path = budget_investments_path(budget, heading_id: heading.id, unselected: 1) + expect(page).to have_current_path(expected_path) + end + + scenario "Shows unselected link for group with many headings" do + group = create(:budget_group, name: 'Districts', budget: budget) + heading1 = create(:budget_heading, name: 'Carabanchel', group: group) + heading2 = create(:budget_heading, name: 'Barajas', group: group) + + visit budget_path(budget) + + click_link 'See investments not selected for balloting phase' + + click_link 'Districts' + click_link 'Carabanchel' + + expected_path = budget_investments_path(budget, heading_id: heading1.id, unselected: 1) + expect(page).to have_current_path(expected_path) + end + end end From 8e7ca16c4745ad68426ffe3895f2a08bb8dd945e Mon Sep 17 00:00:00 2001 From: rgarcia Date: Fri, 5 May 2017 20:07:24 +0200 Subject: [PATCH 596/613] makes ballot's back link point to referer --- .../budgets/ballot/lines_controller.rb | 6 ++++- app/controllers/budgets/ballots_controller.rb | 6 +++++ app/views/budgets/ballot/_ballot.html.erb | 2 +- spec/features/budgets/ballots_spec.rb | 26 +++++++++++++++++-- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/app/controllers/budgets/ballot/lines_controller.rb b/app/controllers/budgets/ballot/lines_controller.rb index 2feb83e5e..522589dfe 100644 --- a/app/controllers/budgets/ballot/lines_controller.rb +++ b/app/controllers/budgets/ballot/lines_controller.rb @@ -7,8 +7,8 @@ module Budgets before_action :load_ballot before_action :load_tag_cloud before_action :load_categories - before_action :load_investments + before_action :load_ballot_referer load_and_authorize_resource :budget load_and_authorize_resource :ballot, class: "Budget::Ballot", through: :budget @@ -73,6 +73,10 @@ module Budgets @categories = ActsAsTaggableOn::Tag.where("kind = 'category'").order(:name) end + def load_ballot_referer + @ballot_referer = session[:ballot_referer] + end + end end end diff --git a/app/controllers/budgets/ballots_controller.rb b/app/controllers/budgets/ballots_controller.rb index ce531e145..b5b63b4aa 100644 --- a/app/controllers/budgets/ballots_controller.rb +++ b/app/controllers/budgets/ballots_controller.rb @@ -3,9 +3,11 @@ module Budgets before_action :authenticate_user! load_and_authorize_resource :budget before_action :load_ballot + after_action :store_referer, only: [:show] def show authorize! :show, @ballot + session[:ballot_referer] = request.referer render template: "budgets/ballot/show" end @@ -16,5 +18,9 @@ module Budgets @ballot = @budget.balloting? ? query.first_or_create : query.first_or_initialize end + def store_referer + session[:ballot_referer] = request.referer + end + end end diff --git a/app/views/budgets/ballot/_ballot.html.erb b/app/views/budgets/ballot/_ballot.html.erb index b83005185..0bf49097f 100644 --- a/app/views/budgets/ballot/_ballot.html.erb +++ b/app/views/budgets/ballot/_ballot.html.erb @@ -1,6 +1,6 @@
    - <%= render 'shared/back_link' %> + <%= back_link_to @ballot_referer %>

    <%= t("budgets.ballots.show.title") %>

    diff --git a/spec/features/budgets/ballots_spec.rb b/spec/features/budgets/ballots_spec.rb index 50670079c..b79d3c468 100644 --- a/spec/features/budgets/ballots_spec.rb +++ b/spec/features/budgets/ballots_spec.rb @@ -350,7 +350,7 @@ feature 'Ballots' do end - scenario 'Removing spending proposals from ballot', :js do + scenario 'Removing investments from ballot', :js do investment = create(:budget_investment, :selected, price: 10, heading: new_york) ballot = create(:budget_ballot, user: user, budget: budget) ballot.investments << investment @@ -368,7 +368,7 @@ feature 'Ballots' do expect(page).to have_content("You have voted 0 proposals") end - scenario 'Removing spending proposals from ballot (sidebar)', :js do + scenario 'Removing investments from ballot (sidebar)', :js do investment1 = create(:budget_investment, :selected, price: 10000, heading: new_york) investment2 = create(:budget_investment, :selected, price: 20000, heading: new_york) @@ -405,6 +405,28 @@ feature 'Ballots' do end end + scenario 'Back link after removing an investment from Ballot', :js do + investment = create(:budget_investment, :selected, heading: new_york, price: 10) + + login_as(user) + visit budget_investments_path(budget, heading_id: new_york.id) + add_to_ballot(investment) + + click_link "Check my ballot" + + expect(page).to have_content("You have voted one proposal") + + within("#budget_investment_#{investment.id}") do + find(".remove-investment-project").trigger('click') + end + + expect(page).to have_content("You have voted 0 proposals") + + click_link "Go back" + + expect(page).to have_current_path(budget_investments_path(budget, heading_id: new_york.id)) + end + context 'Permissions' do scenario 'User not logged in', :js do From fa825185f57630ca0dcf1bd420cb306e559c5e90 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sat, 6 May 2017 03:37:11 +0200 Subject: [PATCH 597/613] adds model specs for investment filters --- spec/models/budget/investment_spec.rb | 86 +++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index e9d5ccd13..2c5f03738 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -337,6 +337,92 @@ describe Budget::Investment do end end + describe "apply_filters_and_search" do + + let(:budget) { create(:budget) } + + it "returns feasible investments" do + investment1 = create(:budget_investment, :feasible, budget: budget) + investment2 = create(:budget_investment, :feasible, budget: budget) + investment3 = create(:budget_investment, :unfeasible, budget: budget) + + results = Budget::Investment::apply_filters_and_search(budget, {}, :feasible) + + expect(results).to include investment1 + expect(results).to include investment2 + expect(results).to_not include investment3 + end + + it "returns unfeasible investments" do + investment1 = create(:budget_investment, :unfeasible, budget: budget) + investment2 = create(:budget_investment, :unfeasible, budget: budget) + investment3 = create(:budget_investment, :feasible, budget: budget) + + results = Budget::Investment::apply_filters_and_search(budget, {}, :unfeasible) + + expect(results).to include investment1 + expect(results).to include investment2 + expect(results).to_not include investment3 + end + + it "returns selected investments" do + budget.update(phase: "balloting") + + investment1 = create(:budget_investment, :feasible, :selected, budget: budget) + investment2 = create(:budget_investment, :feasible, :selected, budget: budget) + investment3 = create(:budget_investment, :feasible, :unselected, budget: budget) + + results = Budget::Investment::apply_filters_and_search(budget, {}, :selected) + + expect(results).to include investment1 + expect(results).to include investment2 + expect(results).to_not include investment3 + end + + it "returns unselected investments" do + budget.update(phase: "balloting") + + investment1 = create(:budget_investment, :feasible, :unselected, budget: budget) + investment2 = create(:budget_investment, :feasible, :unselected, budget: budget) + investment3 = create(:budget_investment, :feasible, :selected, budget: budget) + + results = Budget::Investment::apply_filters_and_search(budget, {}, :unselected) + + expect(results).to include investment1 + expect(results).to include investment2 + expect(results).to_not include investment3 + end + + it "returns investmens by heading" do + group = create(:budget_group, budget: budget) + + heading1 = create(:budget_heading, group: group) + heading2 = create(:budget_heading, group: group) + + investment1 = create(:budget_investment, heading: heading1, budget: budget) + investment2 = create(:budget_investment, heading: heading1, budget: budget) + investment3 = create(:budget_investment, heading: heading2, budget: budget) + + results = Budget::Investment::apply_filters_and_search(budget, heading_id: heading1.id) + + expect(results).to include investment1 + expect(results).to include investment2 + expect(results).to_not include investment3 + end + + it "returns investments by search string" do + investment1 = create(:budget_investment, title: "health for all", budget: budget) + investment2 = create(:budget_investment, title: "improved health", budget: budget) + investment3 = create(:budget_investment, title: "finance", budget: budget) + + results = Budget::Investment::apply_filters_and_search(budget, search: "health") + + expect(results).to include investment1 + expect(results).to include investment2 + expect(results).to_not include investment3 + end + end + describe "search" do context "tags" do From c0488c3b3c0c1df30337ec929c8b0bd767ef1718 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sat, 6 May 2017 03:37:29 +0200 Subject: [PATCH 598/613] refactors investment filters --- app/controllers/application_controller.rb | 6 ++++ app/controllers/budgets/groups_controller.rb | 3 ++ .../budgets/investments_controller.rb | 5 ++- app/controllers/budgets_controller.rb | 3 ++ app/models/budget/investment.rb | 17 +++------- app/views/budgets/groups/show.html.erb | 23 ++++++++------ app/views/budgets/investments/index.html.erb | 4 +-- app/views/budgets/show.html.erb | 26 +++++++++------- spec/factories.rb | 6 ++++ spec/features/budgets/ballots_spec.rb | 10 ++++-- spec/features/budgets/investments_spec.rb | 31 ++++++++++--------- spec/features/tags/budget_investments_spec.rb | 10 +++--- 12 files changed, 85 insertions(+), 59 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 3e1b78d31..495a25314 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -114,4 +114,10 @@ class ApplicationController < ActionController::Base store_location_for(:user, request.path) end end + + def set_default_budget_filter + if @budget.try(:balloting?) + params[:filter] ||= "selected" + end + end end diff --git a/app/controllers/budgets/groups_controller.rb b/app/controllers/budgets/groups_controller.rb index e55974a6a..d84eb2fdd 100644 --- a/app/controllers/budgets/groups_controller.rb +++ b/app/controllers/budgets/groups_controller.rb @@ -3,6 +3,9 @@ module Budgets load_and_authorize_resource :budget load_and_authorize_resource :group, class: "Budget::Group" + before_action :set_default_budget_filter, only: :show + has_filters %w{not_unfeasible feasible unfeasible unselected selected}, only: [:show] + def show end diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 7f9c6e7ee..7eb1b1291 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -14,18 +14,20 @@ module Budgets before_action :load_heading, only: [:index, :show] before_action :set_random_seed, only: :index before_action :load_categories, only: [:index, :new, :create] + before_action :set_default_budget_filter, only: :index feature_flag :budgets has_orders %w{most_voted newest oldest}, only: :show has_orders ->(c) { c.instance_variable_get(:@budget).investments_orders }, only: :index + has_filters %w{not_unfeasible feasible unfeasible unselected selected}, only: [:index, :show] invisible_captcha only: [:create, :update], honeypot: :subtitle, scope: :budget_investment respond_to :html, :js def index - @investments = @investments.apply_filters_and_search(@budget, params).send("sort_by_#{@current_order}").page(params[:page]).per(10).for_render + @investments = @investments.apply_filters_and_search(@budget, params, @current_filter).send("sort_by_#{@current_order}").page(params[:page]).per(10).for_render @investment_ids = @investments.pluck(:id) load_investment_votes(@investments) @tag_cloud = tag_cloud @@ -107,6 +109,7 @@ module Budgets def tag_cloud TagCloud.new(Budget::Investment, params[:search]) end + end end diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb index ee26f3223..2a53c410b 100644 --- a/app/controllers/budgets_controller.rb +++ b/app/controllers/budgets_controller.rb @@ -3,6 +3,9 @@ class BudgetsController < ApplicationController feature_flag :budgets load_and_authorize_resource + before_action :set_default_budget_filter, only: :show + has_filters %w{not_unfeasible feasible unfeasible unselected selected}, only: :show + respond_to :html, :js def show diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 0b4470383..64adbaddf 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -46,8 +46,8 @@ class Budget scope :not_unfeasible, -> { where.not(feasibility: "unfeasible") } scope :undecided, -> { where(feasibility: "undecided") } scope :with_supports, -> { where('cached_votes_up > 0') } - scope :selected, -> { where(selected: true) } - scope :unselected, -> { where(selected: false) } + scope :selected, -> { feasible.where(selected: true) } + scope :unselected, -> { feasible.where(selected: false) } scope :last_week, -> { where("created_at >= ?", 7.days.ago)} scope :by_group, -> (group_id) { where(group_id: group_id) } @@ -234,17 +234,9 @@ class Budget budget.formatted_amount(price) end - def self.apply_filters_and_search(budget, params) + def self.apply_filters_and_search(budget, params, current_filter=nil) investments = all - - if budget.balloting? && params[:unfeasible].blank? && params[:unselected].blank? - investments = investments.selected - elsif budget.balloting? && params[:unfeasible].blank? && params[:unselected].present? - investments = investments.feasible.unselected - else - investments = params[:unfeasible].present? ? investments.unfeasible : investments.not_unfeasible - end - + investments = investments.send(current_filter) if current_filter.present? investments = investments.by_heading(params[:heading_id]) if params[:heading_id].present? investments = investments.search(params[:search]) if params[:search].present? investments @@ -256,5 +248,6 @@ class Budget self.group_id = self.heading.try(:group_id) if self.heading_id_changed? self.budget_id ||= self.heading.try(:group).try(:budget_id) end + end end diff --git a/app/views/budgets/groups/show.html.erb b/app/views/budgets/groups/show.html.erb index 8fbe028b3..d2e1c01fc 100644 --- a/app/views/budgets/groups/show.html.erb +++ b/app/views/budgets/groups/show.html.erb @@ -7,13 +7,13 @@
    -<% if params[:unfeasible] %> +<% if @current_filter == "unfeasible" %>

    <%= t("budgets.groups.show.unfeasible_title") %>

    -<% elsif params[:unselected] %> +<% elsif @current_filter == "unselected" %>

    <%= t("budgets.groups.show.unselected_title") %>

    @@ -31,8 +31,7 @@ class="<%= css_for_ballot_heading(heading) %>"> <%= link_to heading.name, budget_investments_path(heading_id: heading.id, - unfeasible: params[:unfeasible], - unselected: params[:unselected]), + filter: @current_filter), data: { no_turbolink: true } %>
    <% end %> @@ -46,20 +45,24 @@
    -<% if params[:unfeasible].blank? %> +<% unless @current_filter == "unfeasible" %>
    - <%= link_to t("budgets.groups.show.unfeasible"), - budget_path(@budget, unfeasible: 1) %> + + <%= link_to t("budgets.groups.show.unfeasible"), + budget_path(@budget, filter: "unfeasible") %> +
    <% end %> -<% if params[:unselected].blank? %> +<% unless @current_filter == "unselected" %>
    - <%= link_to t("budgets.groups.show.unselected"), - budget_path(@budget, unselected: 1) %> + + <%= link_to t("budgets.groups.show.unselected"), + budget_path(@budget, filter: "unselected") %> +
    <% end %> diff --git a/app/views/budgets/investments/index.html.erb b/app/views/budgets/investments/index.html.erb index 50a2866f9..95b60f55b 100644 --- a/app/views/budgets/investments/index.html.erb +++ b/app/views/budgets/investments/index.html.erb @@ -16,7 +16,7 @@
    - <% if params[:unfeasible].present? %> + <% if @current_filter == "unfeasible" %>

    <%= t("budgets.investments.index.unfeasible") %>: <%= @heading.name %>

    <%= t("budgets.investments.index.unfeasible_text", @@ -34,7 +34,7 @@ <% end %>
    - <%= render('shared/order_links', i18n_namespace: "budgets.investments.index") unless params[:unfeasible].present? %> + <%= render('shared/order_links', i18n_namespace: "budgets.investments.index") unless @current_filter == "unfeasible" %> <% @investments.each do |investment| %> <%= render partial: '/budgets/investments/investment', locals: { diff --git a/app/views/budgets/show.html.erb b/app/views/budgets/show.html.erb index d6a571b46..f67b3ca9d 100644 --- a/app/views/budgets/show.html.erb +++ b/app/views/budgets/show.html.erb @@ -37,9 +37,9 @@
    - <% if params[:unfeasible] %> + <% if @current_filter == "unfeasible" %>

    <%= t("budgets.show.unfeasible_title") %>

    - <% elsif params[:unselected] %> + <% elsif @current_filter == "unselected" %>

    <%= t("budgets.show.unselected_title") %>

    <% end %>
    @@ -54,14 +54,12 @@ <%= link_to group.name, budget_investments_path(@budget, heading_id: group.headings.first.id, - unfeasible: params[:unfeasible], - unselected: params[:unselected]), + filter: @current_filter), data: { no_turbolink: true } %> <% else %> <%= link_to group.name, budget_group_path(@budget, group, - unfeasible: params[:unfeasible], - unselected: params[:unselected]) %> + filter: @current_filter) %> <% end %>
    @@ -72,20 +70,24 @@ -<% unless params[:unfeasible] %> +<% unless @current_filter == "unfeasible" %>
    - <%= link_to t("budgets.show.unfeasible"), - budget_path(@budget, unfeasible: 1) %> + + <%= link_to t("budgets.show.unfeasible"), + budget_path(@budget, filter: "unfeasible") %> +
    <% end %> -<% unless params[:unselected] %> +<% unless @current_filter == "unselected" %>
    - <%= link_to t("budgets.show.unselected"), - budget_path(@budget, unselected: 1) %> + + <%= link_to t("budgets.show.unselected"), + budget_path(@budget, filter: "unselected") %> +
    <% end %> diff --git a/spec/factories.rb b/spec/factories.rb index b295fd60c..f0a4fc5a2 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -284,6 +284,12 @@ FactoryGirl.define do feasibility "feasible" valuation_finished true end + + trait :unselected do + selected false + feasibility "feasible" + valuation_finished true + end end factory :budget_ballot, class: 'Budget::Ballot' do diff --git a/spec/features/budgets/ballots_spec.rb b/spec/features/budgets/ballots_spec.rb index 50670079c..7b3f3d1af 100644 --- a/spec/features/budgets/ballots_spec.rb +++ b/spec/features/budgets/ballots_spec.rb @@ -447,10 +447,12 @@ feature 'Ballots' do end scenario 'Unselected investments' do - investment = create(:budget_investment, heading: new_york) + investment = create(:budget_investment, heading: new_york, title: "WTF asdfasfd") login_as(user) - visit budget_investments_path(budget, heading_id: new_york.id, unfeasible: 1) + visit budget_path(budget) + click_link states.name + click_link new_york.name expect(page).to_not have_css("#budget_investment_#{investment.id}") end @@ -459,7 +461,9 @@ feature 'Ballots' do investment = create(:budget_investment, feasibility: "undecided", heading: new_york) login_as(user) - visit budget_investments_path(budget, heading_id: new_york.id) + visit budget_path(budget) + click_link states.name + click_link new_york.name within("#budget-investments") do expect(page).to_not have_css("div.ballot") diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 69d995311..0df280fd3 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -8,10 +8,14 @@ feature 'Budget Investments' do let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) } scenario 'Index' do - investments = [create(:budget_investment, heading: heading), create(:budget_investment, heading: heading), create(:budget_investment, :feasible, heading: heading)] + investments = [create(:budget_investment, heading: heading), + create(:budget_investment, heading: heading), + create(:budget_investment, :feasible, heading: heading)] + unfeasible_investment = create(:budget_investment, :unfeasible, heading: heading) - visit budget_investments_path(budget, heading_id: heading.id) + visit budget_path(budget) + click_link "Health" expect(page).to have_selector('#budget-investments .budget-investment', count: 3) investments.each do |investment| @@ -56,7 +60,7 @@ feature 'Budget Investments' do investment3 = create(:budget_investment, heading: heading) investment4 = create(:budget_investment, :feasible, heading: heading) - visit budget_investments_path(budget_id: budget.id, heading_id: heading.id, unfeasible: 1) + visit budget_investments_path(budget_id: budget.id, heading_id: heading.id, filter: "unfeasible") within("#budget-investments") do expect(page).to have_css('.budget-investment', count: 1) @@ -77,7 +81,7 @@ feature 'Budget Investments' do click_link "All City" - expected_path = budget_investments_path(budget, heading_id: heading.id, unfeasible: 1) + expected_path = budget_investments_path(budget, heading_id: heading.id, filter: "unfeasible") expect(page).to have_current_path(expected_path) end @@ -93,7 +97,7 @@ feature 'Budget Investments' do click_link 'Districts' click_link 'Carabanchel' - expected_path = budget_investments_path(budget, heading_id: heading1.id, unfeasible: 1) + expected_path = budget_investments_path(budget, heading_id: heading1.id, filter: "unfeasible") expect(page).to have_current_path(expected_path) end end @@ -516,8 +520,6 @@ feature 'Budget Investments' do expect(page).to have_content "€10,000" end - - scenario "Sidebar in show should display vote text" do investment = create(:budget_investment, :selected, budget: budget) visit budget_investment_path(budget, investment) @@ -537,7 +539,6 @@ feature 'Budget Investments' do carabanchel_heading = create(:budget_heading, group: group, name: "Carabanchel") new_york_heading = create(:budget_heading, group: group, name: "New York") - sp1 = create(:budget_investment, :selected, price: 1, heading: global_heading) sp2 = create(:budget_investment, :selected, price: 10, heading: global_heading) sp3 = create(:budget_investment, :selected, price: 100, heading: global_heading) @@ -603,12 +604,12 @@ feature 'Budget Investments' do end scenario 'Show unselected budget investments' do - investment1 = create(:budget_investment, :feasible, heading: heading, valuation_finished: true) - investment2 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) - investment3 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) - investment4 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) + investment1 = create(:budget_investment, :unselected, :feasible, heading: heading, valuation_finished: true) + investment2 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) + investment3 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) + investment4 = create(:budget_investment, :selected, :feasible, heading: heading, valuation_finished: true) - visit budget_investments_path(budget_id: budget.id, heading_id: heading.id, unselected: 1) + visit budget_investments_path(budget_id: budget.id, heading_id: heading.id, filter: "unselected") within("#budget-investments") do expect(page).to have_css('.budget-investment', count: 1) @@ -629,7 +630,7 @@ feature 'Budget Investments' do click_link "All City" - expected_path = budget_investments_path(budget, heading_id: heading.id, unselected: 1) + expected_path = budget_investments_path(budget, heading_id: heading.id, filter: "unselected") expect(page).to have_current_path(expected_path) end @@ -645,7 +646,7 @@ feature 'Budget Investments' do click_link 'Districts' click_link 'Carabanchel' - expected_path = budget_investments_path(budget, heading_id: heading1.id, unselected: 1) + expected_path = budget_investments_path(budget, heading_id: heading1.id, filter: "unselected") expect(page).to have_current_path(expected_path) end diff --git a/spec/features/tags/budget_investments_spec.rb b/spec/features/tags/budget_investments_spec.rb index 28d19333f..4c978c740 100644 --- a/spec/features/tags/budget_investments_spec.rb +++ b/spec/features/tags/budget_investments_spec.rb @@ -199,11 +199,12 @@ feature 'Tags' do if budget.balloting? [investment1, investment2, investment3].each do |investment| - investment.update(selected: true) + investment.update(selected: true, feasibility: "feasible") end end - visit budget_investments_path(budget, heading_id: heading.id) + visit budget_path(budget) + click_link group.name within "#tag-cloud" do click_link "Medio Ambiente" @@ -246,11 +247,12 @@ feature 'Tags' do if budget.balloting? [investment1, investment2, investment3].each do |investment| - investment.update(selected: true) + investment.update(selected: true, feasibility: "feasible") end end - visit budget_investments_path(budget, heading_id: heading.id, search: 'Economía') + visit budget_path(budget) + click_link group.name within "#categories" do click_link "Medio Ambiente" From 39ed526b89bd46a8dc3bee28a58763f68a874333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 8 May 2017 13:22:53 +0200 Subject: [PATCH 599/613] displays correct heading name when reviewing ballot --- app/views/budgets/ballot/_ballot.html.erb | 2 +- spec/features/budgets/ballots_spec.rb | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/budgets/ballot/_ballot.html.erb b/app/views/budgets/ballot/_ballot.html.erb index 0bf49097f..bfd9bc668 100644 --- a/app/views/budgets/ballot/_ballot.html.erb +++ b/app/views/budgets/ballot/_ballot.html.erb @@ -24,7 +24,7 @@

    - <%= group.name %> - <%= group.headings.first.name %> + <%= group.name %> - <%= @ballot.heading_for_group(group).name %>

    <% if @ballot.has_lines_in_group?(group) %>

    diff --git a/spec/features/budgets/ballots_spec.rb b/spec/features/budgets/ballots_spec.rb index e932b577f..446fb3984 100644 --- a/spec/features/budgets/ballots_spec.rb +++ b/spec/features/budgets/ballots_spec.rb @@ -313,12 +313,14 @@ feature 'Ballots' do expect(current_path).to eq(budget_investments_path(budget)) end - scenario 'Displaying the correct count & amount' do + scenario 'Displaying the correct group, heading, count & amount' do group1 = create(:budget_group, budget: budget) group2 = create(:budget_group, budget: budget) + create(:budget_heading, name: "District A", group: group1, price: 100) heading1 = create(:budget_heading, name: "District 1", group: group1, price: 100) heading2 = create(:budget_heading, name: "District 2", group: group2, price: 50) + create(:budget_heading, name: "District Z", group: group1, price: 100) investment1 = create(:budget_investment, :selected, price: 10, heading: heading1) investment2 = create(:budget_investment, :selected, price: 10, heading: heading1) From 216b60f22e4cbcfebbac0a173a6a8b7aab0eb3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Mon, 8 May 2017 13:27:17 +0200 Subject: [PATCH 600/613] orders groups in ballot view --- app/views/budgets/ballot/_ballot.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/budgets/ballot/_ballot.html.erb b/app/views/budgets/ballot/_ballot.html.erb index 0bf49097f..1e805322e 100644 --- a/app/views/budgets/ballot/_ballot.html.erb +++ b/app/views/budgets/ballot/_ballot.html.erb @@ -20,7 +20,7 @@
    - <% @ballot.groups.each do |group| %> + <% @ballot.groups.order(name: :asc).each do |group| %>

    From c0afb94cfab4dae45a298bb1f3e5c77d8b973328 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 8 May 2017 14:33:07 +0200 Subject: [PATCH 601/613] improves ballot page when shows several groups --- app/assets/stylesheets/participation.scss | 16 +++++++------ app/views/budgets/ballot/_ballot.html.erb | 29 ++++++++++++----------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss index ad413925b..4cb3fbb34 100644 --- a/app/assets/stylesheets/participation.scss +++ b/app/assets/stylesheets/participation.scss @@ -1064,13 +1064,16 @@ } } - h3.subtitle { - border-bottom: 3px solid $budget; + .ballot-content { + border: 2px solid #F9F9F9; + border-radius: rem-calc(6); + padding: $line-height/2; + } - span { - font-size: $base-font-size; - font-weight: normal; - } + .subtitle { + border-left: 2px solid $budget; + margin: $line-height/2 0; + padding-left: $line-height/2; } .amount-spent { @@ -1101,7 +1104,6 @@ ul.ballot-list { } span { - color: #9f9f9f; display: block; font-style: italic; } diff --git a/app/views/budgets/ballot/_ballot.html.erb b/app/views/budgets/ballot/_ballot.html.erb index aa37828b2..72a0d1c6e 100644 --- a/app/views/budgets/ballot/_ballot.html.erb +++ b/app/views/budgets/ballot/_ballot.html.erb @@ -19,13 +19,19 @@

    -
    - <% @ballot.groups.order(name: :asc).each do |group| %> -
    -

    - <%= group.name %> - <%= @ballot.heading_for_group(group).name %> -

    + <% @ballot.groups.order(name: :asc).each do |group| %> +
    +
    +
    +

    + <%= group.name %> - <%= @ballot.heading_for_group(group).name %> +

    + + <%= t("budgets.ballots.show.remaining", + amount: @ballot.formatted_amount_available(@ballot.heading_for_group(group))).html_safe %> + +
    <% if @ballot.has_lines_in_group?(group) %>

    <%= t("budgets.ballots.show.amount_spent") %> @@ -43,12 +49,7 @@ <%= render partial: 'budgets/ballot/investment', collection: @ballot.investments.by_group(group.id) %> - -

    - <%= t("budgets.ballots.show.remaining", - amount: @ballot.formatted_amount_available(@ballot.heading_for_group(group))).html_safe %> -

    - <% end %> -
    +
    + <% end %>
    From b29a353ce51d37efe704890eb3b8368414c71324 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Cabeza Date: Mon, 8 May 2017 15:06:18 +0200 Subject: [PATCH 602/613] adds rel canonical on main sections --- app/views/budgets/index.html.erb | 4 ++++ app/views/debates/index.html.erb | 3 +++ app/views/layouts/application.html.erb | 1 + app/views/pages/more_info/index.html.erb | 3 +++ app/views/polls/index.html.erb | 3 +++ app/views/proposals/index.html.erb | 3 +++ app/views/shared/_canonical.html.erb | 1 + 7 files changed, 18 insertions(+) create mode 100644 app/views/shared/_canonical.html.erb diff --git a/app/views/budgets/index.html.erb b/app/views/budgets/index.html.erb index f3e386d27..9f5ab0ab2 100644 --- a/app/views/budgets/index.html.erb +++ b/app/views/budgets/index.html.erb @@ -1,3 +1,7 @@ +<% content_for :canonical do %> + <%= render "shared/canonical", href: budgets_url %> +<% end %> +
    diff --git a/app/views/debates/index.html.erb b/app/views/debates/index.html.erb index fd5e45059..b7796f0ba 100644 --- a/app/views/debates/index.html.erb +++ b/app/views/debates/index.html.erb @@ -4,6 +4,9 @@ search_path: debates_path(page: 1), i18n_namespace: "debates.index.search_form" %> <% end %> +<% content_for :canonical do %> + <%= render "shared/canonical", href: debates_url %> +<% end %>

    <%= t("shared.outline.debates") %>

    diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 7f66b524e..d410140e5 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -7,6 +7,7 @@ <%= render "layouts/tracking_data" %> <%= render "layouts/meta_tags" %> <%= content_for?(:title) ? yield(:title) : setting['org_name'] %> + <%= content_for :canonical %> <%= stylesheet_link_tag "application" %>