From d3660d1245d014a4b1780197eb67f29d02e70dfc Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Jun 2018 18:53:36 +0200 Subject: [PATCH 01/16] Create Budget Poll offline/online vote feature test --- spec/features/budget_polls/voter_spec.rb | 91 ++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 spec/features/budget_polls/voter_spec.rb diff --git a/spec/features/budget_polls/voter_spec.rb b/spec/features/budget_polls/voter_spec.rb new file mode 100644 index 000000000..2b887c29c --- /dev/null +++ b/spec/features/budget_polls/voter_spec.rb @@ -0,0 +1,91 @@ +require "rails_helper" + +feature "BudgetPolls", :with_frozen_time do + let(:budget) { create(:budget, :balloting) } + let(:poll) { create(:poll, :current) } + let(:booth) { create(:poll_booth) } + let(:officer) { create(:poll_officer) } + let(:admin) { create(:administrator) } + + background do + create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection) + booth_assignment = create(:poll_booth_assignment, poll: poll, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment, date: Date.current) + end + + context "Offline" do + scenario "A citizen can cast a paper vote", :js do + user = create(:user, :in_census) + + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + + within("#poll_#{poll.id}") do + click_button("Confirm vote") + expect(page).not_to have_button("Confirm vote") + expect(page).to have_content "Vote introduced!" + end + + expect(Poll::Voter.count).to eq(1) + expect(Poll::Voter.first.origin).to eq("booth") + + visit root_path + click_link "Sign out" + login_as(admin.user) + visit admin_poll_recounts_path(poll) + + within("#total_system") do + expect(page).to have_content "1" + end + + within("#poll_booth_assignment_#{Poll::BoothAssignment.where(poll: poll, booth: booth).first.id}_recounts") do + expect(page).to have_content "1" + end + end + + scenario "A citizen cannot vote offline again", :js do + user = create(:user, :in_census) + + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + within("#poll_#{poll.id}") do + click_button("Confirm vote") + end + + visit new_officing_residence_path + officing_verify_residence + + within("#poll_#{poll.id}") do + expect(page).to have_content "Has already participated in this poll" + end + end + + scenario "A citizen cannot vote online after voting offline" do + # create scenario for an user that voted offline + + # Check the citizen cannot vote online + end + end + + context "Online" do + scenario "A citizen can cast vote online" do + # Login as User + # Cast a vote for an investment + end + + scenario "A citizen cannot vote offline after voting online" do + # create scenario for an user that voted online + + # Login as Poll Officer + # Check the citizen cannot vote offline + end + + end +end From 20a3f6539dbaa6cb2fc54f84ebb5ea28255a8f78 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 4 Jun 2018 20:00:09 +0200 Subject: [PATCH 02/16] Add association between polls and budgets --- app/models/budget.rb | 2 ++ app/models/poll.rb | 1 + db/migrate/20180604173248_add_budget_to_polls.rb | 5 +++++ db/schema.rb | 3 +++ 4 files changed, 11 insertions(+) create mode 100644 db/migrate/20180604173248_add_budget_to_polls.rb diff --git a/app/models/budget.rb b/app/models/budget.rb index ecfacc5c0..28fb8c5ca 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -21,6 +21,8 @@ class Budget < ActiveRecord::Base has_many :headings, through: :groups has_many :phases, class_name: Budget::Phase + has_one :poll + before_validation :sanitize_descriptions after_create :generate_phases diff --git a/app/models/poll.rb b/app/models/poll.rb index 9276cf9fb..9b300c150 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -23,6 +23,7 @@ class Poll < ActiveRecord::Base has_and_belongs_to_many :geozones belongs_to :author, -> { with_hidden }, class_name: "User", foreign_key: "author_id" + belongs_to :budget validates_translation :name, presence: true validate :date_range diff --git a/db/migrate/20180604173248_add_budget_to_polls.rb b/db/migrate/20180604173248_add_budget_to_polls.rb new file mode 100644 index 000000000..74d45e1a8 --- /dev/null +++ b/db/migrate/20180604173248_add_budget_to_polls.rb @@ -0,0 +1,5 @@ +class AddBudgetToPolls < ActiveRecord::Migration + def change + add_reference :polls, :budget, index: { unique: true }, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 991f6d327..96e3d3487 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1129,8 +1129,10 @@ ActiveRecord::Schema.define(version: 20190205131722) do t.boolean "stats_enabled", default: false t.datetime "created_at" t.datetime "updated_at" + t.integer "budget_id" end + add_index "polls", ["budget_id"], name: "index_polls_on_budget_id", unique: true, using: :btree add_index "polls", ["starts_at", "ends_at"], name: "index_polls_on_starts_at_and_ends_at", using: :btree create_table "progress_bar_translations", force: :cascade do |t| @@ -1614,6 +1616,7 @@ ActiveRecord::Schema.define(version: 20190205131722) do add_foreign_key "poll_recounts", "poll_booth_assignments", column: "booth_assignment_id" add_foreign_key "poll_recounts", "poll_officer_assignments", column: "officer_assignment_id" add_foreign_key "poll_voters", "polls" + add_foreign_key "polls", "budgets" add_foreign_key "proposals", "communities" add_foreign_key "related_content_scores", "related_contents" add_foreign_key "related_content_scores", "users" From aa7441271d86418c2c2314abcd4c1aee6354a106 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 4 Jun 2018 20:02:00 +0200 Subject: [PATCH 03/16] Prevent balloting online after casting a ballot offline --- app/models/budget/ballot.rb | 4 ++++ app/models/budget/investment.rb | 1 + config/locales/en/budgets.yml | 1 + config/locales/es/budgets.yml | 1 + spec/features/budget_polls/voter_spec.rb | 30 ++++++++++++++++++++---- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/app/models/budget/ballot.rb b/app/models/budget/ballot.rb index c35222f3a..7dc618360 100644 --- a/app/models/budget/ballot.rb +++ b/app/models/budget/ballot.rb @@ -70,5 +70,9 @@ class Budget investments.where(group: group).first.heading end + def casted_offline? + budget.poll&.voted_by?(user) + end + end end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 4dae6c3ac..fa95de72e 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -241,6 +241,7 @@ class Budget return :no_ballots_allowed unless budget.balloting? return :different_heading_assigned_html unless ballot.valid_heading?(heading) return :not_enough_money_html if ballot.present? && !enough_money?(ballot) + return :casted_offline if ballot.casted_offline? end def permission_problem(user) diff --git a/config/locales/en/budgets.yml b/config/locales/en/budgets.yml index 3fd88cd48..d7bd7235d 100644 --- a/config/locales/en/budgets.yml +++ b/config/locales/en/budgets.yml @@ -22,6 +22,7 @@ en: no_ballots_allowed: Selecting phase is closed different_heading_assigned_html: "You have already voted a different heading: %{heading_link}" change_ballot: change your votes + casted_offline: You have already participated offline groups: show: title: Select an option diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index c827b2349..982149b5a 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -22,6 +22,7 @@ es: no_ballots_allowed: El periodo de votación está cerrado. different_heading_assigned_html: "Ya has votado proyectos de otra partida: %{heading_link}" change_ballot: cambiar tus votos + casted_offline: Ya has participado presencialmente groups: show: title: Selecciona una opción diff --git a/spec/features/budget_polls/voter_spec.rb b/spec/features/budget_polls/voter_spec.rb index 2b887c29c..8808177f4 100644 --- a/spec/features/budget_polls/voter_spec.rb +++ b/spec/features/budget_polls/voter_spec.rb @@ -2,7 +2,10 @@ require "rails_helper" feature "BudgetPolls", :with_frozen_time do let(:budget) { create(:budget, :balloting) } - let(:poll) { create(:poll, :current) } + let(:group) { create(:budget_group, budget: budget) } + let(:heading) { create(:budget_heading, group: group) } + let(:investment) { create(:budget_investment, :selected, heading: heading) } + let(:poll) { create(:poll, :current, budget: budget) } let(:booth) { create(:poll_booth) } let(:officer) { create(:poll_officer) } let(:admin) { create(:administrator) } @@ -67,10 +70,29 @@ feature "BudgetPolls", :with_frozen_time do end end - scenario "A citizen cannot vote online after voting offline" do - # create scenario for an user that voted offline + scenario "A citizen cannot vote online after voting offline", :js do + user = create(:user, :in_census) - # Check the citizen cannot vote online + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + within("#poll_#{poll.id}") do + click_button("Confirm vote") + end + + expect(page).to have_content "Vote introduced!" + + login_as(user) + + visit budget_investment_path(budget, investment) + find("div.ballot").hover + + within("#budget_investment_#{investment.id}") do + expect(page).to have_content "You have already participated offline" + expect(page).to have_css(".add a", visible: false) + end end end From dac0264b63934aee4ded8ca44787dc02dec8fd49 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 4 Jun 2018 21:08:43 +0200 Subject: [PATCH 04/16] Prevent offline budget vote after voting online --- app/models/poll.rb | 5 ++ spec/features/budget_polls/voter_spec.rb | 59 ++++++++++++++++++------ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/app/models/poll.rb b/app/models/poll.rb index 9b300c150..7b04f45ec 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -72,10 +72,15 @@ class Poll < ActiveRecord::Base end def votable_by?(user) + return false if user_has_an_online_ballot(user) answerable_by?(user) && not_voted_by?(user) end + def user_has_an_online_ballot(user) + budget.present? && budget.ballots.find_by(user: user)&.lines.present? + end + def self.not_voted_by(user) where("polls.id not in (?)", poll_ids_voted_by(user)) end diff --git a/spec/features/budget_polls/voter_spec.rb b/spec/features/budget_polls/voter_spec.rb index 8808177f4..6462f021d 100644 --- a/spec/features/budget_polls/voter_spec.rb +++ b/spec/features/budget_polls/voter_spec.rb @@ -9,6 +9,7 @@ feature "BudgetPolls", :with_frozen_time do let(:booth) { create(:poll_booth) } let(:officer) { create(:poll_officer) } let(:admin) { create(:administrator) } + let!(:user) { create(:user, :in_census) } background do create(:poll_shift, officer: officer, booth: booth, date: Date.current, task: :vote_collection) @@ -18,8 +19,6 @@ feature "BudgetPolls", :with_frozen_time do context "Offline" do scenario "A citizen can cast a paper vote", :js do - user = create(:user, :in_census) - login_through_form_as_officer(officer.user) visit new_officing_residence_path @@ -51,8 +50,6 @@ feature "BudgetPolls", :with_frozen_time do end scenario "A citizen cannot vote offline again", :js do - user = create(:user, :in_census) - login_through_form_as_officer(officer.user) visit new_officing_residence_path @@ -71,8 +68,6 @@ feature "BudgetPolls", :with_frozen_time do end scenario "A citizen cannot vote online after voting offline", :js do - user = create(:user, :in_census) - login_through_form_as_officer(officer.user) visit new_officing_residence_path @@ -97,16 +92,54 @@ feature "BudgetPolls", :with_frozen_time do end context "Online" do - scenario "A citizen can cast vote online" do - # Login as User - # Cast a vote for an investment + scenario "A citizen can cast vote online", :js do + login_as(user) + visit budget_investment_path(budget, investment) + + within("#budget_investment_#{investment.id}") do + find(".add a").click + expect(page).to have_content "Remove" + end end - scenario "A citizen cannot vote offline after voting online" do - # create scenario for an user that voted online + scenario "A citizen cannot vote online again", :js do + login_as(user) + visit budget_investment_path(budget, investment) - # Login as Poll Officer - # Check the citizen cannot vote offline + within("#budget_investment_#{investment.id}") do + find(".add a").click + expect(page).to have_content "Remove" + end + + visit budget_investment_path(budget, investment) + find("div.ballot").hover + + within("#budget_investment_#{investment.id}") do + expect(page).to have_content "Remove vote" + end + end + + scenario "A citizen cannot vote offline after voting online", :js do + login_as(user) + visit budget_investment_path(budget, investment) + + within("#budget_investment_#{investment.id}") do + find(".add a").click + expect(page).to have_content "Remove" + end + + logout + login_through_form_as_officer(officer.user) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content poll.name + + within("#poll_#{poll.id}") do + expect(page).not_to have_button("Confirm vote") + expect(page).to have_content("Has already participated in this poll") + end end end From 7dd314c699e6bce8dfc0f249f1ed51032f47adfb Mon Sep 17 00:00:00 2001 From: rgarcia Date: Thu, 7 Jun 2018 13:07:52 +0200 Subject: [PATCH 05/16] Do not display polls associated to a budget in admin poll questions This section is used to select to which poll a question belongs to. Budget polls are not meant to include questions that come from Citizen Proposals or Government Questions, thus we do not display them --- .../admin/poll/questions_controller.rb | 2 +- app/models/poll.rb | 1 + spec/features/budget_polls/questions_spec.rb | 22 +++++++++++++++++++ spec/models/poll/poll_spec.rb | 20 +++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 spec/features/budget_polls/questions_spec.rb diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index ed39862b2..769a7998c 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -6,7 +6,7 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController load_and_authorize_resource :question, class: "Poll::Question" def index - @polls = Poll.all + @polls = Poll.not_budget @search = search_params[:search] @questions = @questions.search(search_params).page(params[:page]).order("created_at DESC") diff --git a/app/models/poll.rb b/app/models/poll.rb index 7b04f45ec..9d706b020 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -34,6 +34,7 @@ class Poll < ActiveRecord::Base scope :published, -> { where("published = ?", true) } scope :by_geozone_id, ->(geozone_id) { where(geozones: {id: geozone_id}.joins(:geozones)) } scope :public_for_api, -> { all } + scope :not_budget, -> { where(budget_id: nil) } scope :sort_for_list, -> { order(:geozone_restricted, :starts_at, :name) } diff --git a/spec/features/budget_polls/questions_spec.rb b/spec/features/budget_polls/questions_spec.rb new file mode 100644 index 000000000..5e320573b --- /dev/null +++ b/spec/features/budget_polls/questions_spec.rb @@ -0,0 +1,22 @@ +require "rails_helper" + +feature "Poll Questions" do + + before do + admin = create(:administrator).user + login_as(admin) + end + + scenario "Do not display polls associated to a budget" do + budget = create(:budget) + + poll1 = create(:poll, name: "Citizen Proposal Poll") + poll2 = create(:poll, budget: budget, name: "Participatory Budget Poll") + + visit admin_questions_path + + expect(page).to have_select("poll_id", text: "Citizen Proposal Poll") + expect(page).not_to have_select("poll_id", text: "Participatory Budget Poll") + end + +end diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index ced234dd7..85f9e5877 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -258,4 +258,24 @@ describe Poll do end + context "scopes" do + + describe "#not_budget" do + + it "returns polls not associated to a budget" do + budget = create(:budget) + + poll1 = create(:poll) + poll2 = create(:poll) + poll3 = create(:poll, budget: budget) + + expect(Poll.not_budget).to include(poll1) + expect(Poll.not_budget).to include(poll2) + expect(Poll.not_budget).not_to include(poll3) + end + + end + + end + end From f6739dc7e5e9a42087755dbce7b80d1d18daec54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Thu, 7 Jun 2018 18:31:57 +0200 Subject: [PATCH 06/16] Adds "Admin ballots" button in admin budgets index --- app/views/admin/budgets/index.html.erb | 6 ++++++ config/locales/en/admin.yml | 2 ++ config/locales/es/admin.yml | 2 ++ spec/features/admin/budgets_spec.rb | 10 ++++++++++ 4 files changed, 20 insertions(+) diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb index 2be3ae926..eb676842e 100644 --- a/app/views/admin/budgets/index.html.erb +++ b/app/views/admin/budgets/index.html.erb @@ -17,6 +17,7 @@ <%= t("admin.budgets.index.table_investments") %> <%= t("admin.budgets.index.table_edit_groups") %> <%= t("admin.budgets.index.table_edit_budget") %> + <%= t("admin.budgets.index.table_admin_ballots") %> @@ -39,6 +40,11 @@ <%= link_to t("admin.budgets.index.edit_budget"), edit_admin_budget_path(budget) %> + + <% if budget.poll.present? %> + <%= link_to t("admin.budgets.index.admin_ballots"), admin_poll_path(budget.poll) %> + <% end %> + <% end %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 78584d535..5e8f21efe 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -85,8 +85,10 @@ en: table_investments: Investments table_edit_groups: Headings groups table_edit_budget: Edit + table_admin_ballots: Ballots edit_groups: Edit headings groups edit_budget: Edit budget + admin_ballots: Admin ballots no_budgets: "There are no budgets." create: notice: New participatory budget created successfully! diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 5cacec041..8afc248bc 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -85,8 +85,10 @@ es: table_investments: Proyectos de gasto table_edit_groups: Grupos de partidas table_edit_budget: Editar + table_admin_ballots: Urnas edit_groups: Editar grupos de partidas edit_budget: Editar presupuesto + admin_ballots: Gestionar urnas no_budgets: "No hay presupuestos participativos." create: notice: "¡Presupuestos participativos creados con éxito!" diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index e24c344b2..83c9006e7 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -88,6 +88,16 @@ feature "Admin budgets" do end end + scenario "Admin ballots link appears if budget has a poll associated" do + budget = create(:budget) + create(:poll, budget: budget) + + visit admin_budgets_path + + within "#budget_#{budget.id}" do + expect(page).to have_link("Admin ballots") + end + end end context "New" do From acb0a6070ecd35ffee6cf25dbcf9c0113f25db61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 8 Jun 2018 14:58:47 +0200 Subject: [PATCH 07/16] Hides budget polls in polls admin index --- .../admin/poll/polls_controller.rb | 2 +- spec/features/budget_polls/polls_spec.rb | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 spec/features/budget_polls/polls_spec.rb diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index b012aad38..ab8ddaaa2 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -7,7 +7,7 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController before_action :load_geozones, only: [:new, :create, :edit, :update] def index - @polls = Poll.order(starts_at: :desc) + @polls = Poll.not_budget.order(starts_at: :desc) end def show diff --git a/spec/features/budget_polls/polls_spec.rb b/spec/features/budget_polls/polls_spec.rb new file mode 100644 index 000000000..24a3eb15a --- /dev/null +++ b/spec/features/budget_polls/polls_spec.rb @@ -0,0 +1,19 @@ +require "rails_helper" + +feature "Polls" do + + context "Admin index" do + it "Budget polls should not appear in the list" do + login_as(create(:administrator).user) + + poll = create(:poll) + budget_poll = create(:poll, budget: create(:budget)) + + visit admin_polls_path + + expect(page).to have_content(poll.name) + expect(page).not_to have_content(budget_poll.name) + end + end + +end From 22727a987675053a7997023a617e4202cff507c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Checa?= Date: Fri, 8 Jun 2018 14:59:07 +0200 Subject: [PATCH 08/16] Hides budget polls in polls public index --- app/controllers/polls_controller.rb | 2 +- spec/features/budget_polls/polls_spec.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/controllers/polls_controller.rb b/app/controllers/polls_controller.rb index a034846a0..652a9eaae 100644 --- a/app/controllers/polls_controller.rb +++ b/app/controllers/polls_controller.rb @@ -11,7 +11,7 @@ class PollsController < ApplicationController ::Poll::Answer # trigger autoload def index - @polls = @polls.send(@current_filter).includes(:geozones).sort_for_list.page(params[:page]) + @polls = @polls.not_budget.send(@current_filter).includes(:geozones).sort_for_list.page(params[:page]) end def show diff --git a/spec/features/budget_polls/polls_spec.rb b/spec/features/budget_polls/polls_spec.rb index 24a3eb15a..35e2b1b0f 100644 --- a/spec/features/budget_polls/polls_spec.rb +++ b/spec/features/budget_polls/polls_spec.rb @@ -2,6 +2,18 @@ require "rails_helper" feature "Polls" do + context "Public index" do + it "Budget polls should not be listed" do + poll = create(:poll) + budget_poll = create(:poll, budget: create(:budget)) + + visit polls_path + + expect(page).to have_content(poll.name) + expect(page).not_to have_content(budget_poll.name) + end + end + context "Admin index" do it "Budget polls should not appear in the list" do login_as(create(:administrator).user) From b1b88918f0e0671975325e2879decadbf3cc97e6 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 11 Jun 2018 19:17:59 +0200 Subject: [PATCH 09/16] Moving spec to budget_polls folder --- spec/features/admin/budgets_spec.rb | 10 ---------- spec/features/budget_polls/budgets_spec.rb | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 spec/features/budget_polls/budgets_spec.rb diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 83c9006e7..e24c344b2 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -88,16 +88,6 @@ feature "Admin budgets" do end end - scenario "Admin ballots link appears if budget has a poll associated" do - budget = create(:budget) - create(:poll, budget: budget) - - visit admin_budgets_path - - within "#budget_#{budget.id}" do - expect(page).to have_link("Admin ballots") - end - end end context "New" do diff --git a/spec/features/budget_polls/budgets_spec.rb b/spec/features/budget_polls/budgets_spec.rb new file mode 100644 index 000000000..fc1b8939a --- /dev/null +++ b/spec/features/budget_polls/budgets_spec.rb @@ -0,0 +1,21 @@ +require "rails_helper" + +feature "Admin Budgets" do + + background do + admin = create(:administrator).user + login_as(admin) + end + + scenario "Admin ballots link appears if budget has a poll associated" do + budget = create(:budget) + create(:poll, budget: budget) + + visit admin_budgets_path + + within "#budget_#{budget.id}" do + expect(page).to have_link("Admin ballots") + end + end + +end From 8cfcfcb6a796f5c86676dc5c82ba9d516bdc22da Mon Sep 17 00:00:00 2001 From: rgarcia Date: Mon, 11 Jun 2018 19:19:06 +0200 Subject: [PATCH 10/16] Check for link to poll in specs --- spec/features/budget_polls/budgets_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/budget_polls/budgets_spec.rb b/spec/features/budget_polls/budgets_spec.rb index fc1b8939a..d62c07667 100644 --- a/spec/features/budget_polls/budgets_spec.rb +++ b/spec/features/budget_polls/budgets_spec.rb @@ -9,12 +9,12 @@ feature "Admin Budgets" do scenario "Admin ballots link appears if budget has a poll associated" do budget = create(:budget) - create(:poll, budget: budget) + poll = create(:poll, budget: budget) visit admin_budgets_path within "#budget_#{budget.id}" do - expect(page).to have_link("Admin ballots") + expect(page).to have_link("Admin ballots", admin_poll_path(poll)) end end From 6fa75621814af1e12afbd529ccb9c3635c54abfe Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 12 Jun 2018 13:41:03 +0200 Subject: [PATCH 11/16] Automatically create a budget poll if it does not exist --- .../admin/poll/polls_controller.rb | 2 +- app/helpers/budgets_helper.rb | 12 +++++++ app/views/admin/budgets/index.html.erb | 2 ++ spec/features/budget_polls/budgets_spec.rb | 34 +++++++++++++++---- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index ab8ddaaa2..5b0d3108e 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -63,7 +63,7 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController def poll_params attributes = [:name, :starts_at, :ends_at, :geozone_restricted, :results_enabled, - :stats_enabled, geozone_ids: [], + :stats_enabled, :budget_id, geozone_ids: [], image_attributes: image_attributes] params.require(:poll).permit(*attributes, translation_params(Poll)) end diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index df48a08fa..e4a47557b 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -96,4 +96,16 @@ module BudgetsHelper !current_user.voted_in_group?(investment.group) && investment.group.headings.count > 1 end + + def link_to_create_budget_poll(budget) + balloting_phase = budget.phases.where(kind: "balloting").first + + link_to t("admin.budgets.index.admin_ballots"), + admin_polls_path(poll: { + name: budget.name, + budget_id: budget.id, + starts_at: balloting_phase.starts_at, + ends_at: balloting_phase.ends_at }), + method: :post + end end diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb index eb676842e..31388ce3c 100644 --- a/app/views/admin/budgets/index.html.erb +++ b/app/views/admin/budgets/index.html.erb @@ -43,6 +43,8 @@ <% if budget.poll.present? %> <%= link_to t("admin.budgets.index.admin_ballots"), admin_poll_path(budget.poll) %> + <% else %> + <%= link_to_create_budget_poll(budget) %> <% end %> diff --git a/spec/features/budget_polls/budgets_spec.rb b/spec/features/budget_polls/budgets_spec.rb index d62c07667..e85ad4b90 100644 --- a/spec/features/budget_polls/budgets_spec.rb +++ b/spec/features/budget_polls/budgets_spec.rb @@ -7,15 +7,37 @@ feature "Admin Budgets" do login_as(admin) end - scenario "Admin ballots link appears if budget has a poll associated" do - budget = create(:budget) - poll = create(:poll, budget: budget) + context "Index" do - visit admin_budgets_path + scenario "Create poll if the budget does not have a poll associated" do + budget = create(:budget) - within "#budget_#{budget.id}" do - expect(page).to have_link("Admin ballots", admin_poll_path(poll)) + visit admin_budgets_path + + click_link "Admin ballots" + + balloting_phase = budget.phases.where(kind: "balloting").first + + expect(current_path).to match(/admin\/polls\/\d+/) + expect(page).to have_content(budget.name) + expect(page).to have_content(balloting_phase.starts_at.to_date) + expect(page).to have_content(balloting_phase.ends_at.to_date) + + expect(Poll.count).to eq(1) + expect(Poll.last.budget).to eq(budget) end + + scenario "Display link to poll if the budget has a poll associated" do + budget = create(:budget) + poll = create(:poll, budget: budget) + + visit admin_budgets_path + + within "#budget_#{budget.id}" do + expect(page).to have_link("Admin ballots", admin_poll_path(poll)) + end + end + end end From 431c313487aa8cefb27472818cac29a93a931df9 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Tue, 12 Jun 2018 13:41:43 +0200 Subject: [PATCH 12/16] Use `scenario` instead of `it` in feature specs --- spec/features/budget_polls/polls_spec.rb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/features/budget_polls/polls_spec.rb b/spec/features/budget_polls/polls_spec.rb index 35e2b1b0f..d9ae151cf 100644 --- a/spec/features/budget_polls/polls_spec.rb +++ b/spec/features/budget_polls/polls_spec.rb @@ -3,7 +3,8 @@ require "rails_helper" feature "Polls" do context "Public index" do - it "Budget polls should not be listed" do + + scenario "Budget polls should not be listed" do poll = create(:poll) budget_poll = create(:poll, budget: create(:budget)) @@ -12,10 +13,12 @@ feature "Polls" do expect(page).to have_content(poll.name) expect(page).not_to have_content(budget_poll.name) end + end context "Admin index" do - it "Budget polls should not appear in the list" do + + scenario "Budget polls should not appear in the list" do login_as(create(:administrator).user) poll = create(:poll) From fcbb11b26ec2d938fe96b00ecbef9728ebb5acc3 Mon Sep 17 00:00:00 2001 From: decabeza Date: Wed, 13 Jun 2018 15:35:29 +0200 Subject: [PATCH 13/16] Hides question menu on budget poll and changes redirect when create --- .../admin/poll/polls_controller.rb | 7 ++++- app/models/poll.rb | 3 ++ app/views/admin/budgets/index.html.erb | 2 +- app/views/admin/poll/polls/_subnav.html.erb | 30 ++++++++++--------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 5b0d3108e..04a94cce3 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -22,7 +22,12 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController def create @poll = Poll.new(poll_params.merge(author: current_user)) if @poll.save - redirect_to [:admin, @poll], notice: t("flash.actions.create.poll") + notice = t("flash.actions.create.poll") + if @poll.budget.present? + redirect_to admin_poll_booth_assignments_path(@poll), notice: notice + else + redirect_to [:admin, @poll], notice: notice + end else render :new end diff --git a/app/models/poll.rb b/app/models/poll.rb index 9d706b020..553baf036 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -114,4 +114,7 @@ class Poll < ActiveRecord::Base end end + def budget_poll? + budget.present? + end end diff --git a/app/views/admin/budgets/index.html.erb b/app/views/admin/budgets/index.html.erb index 31388ce3c..c63ee4789 100644 --- a/app/views/admin/budgets/index.html.erb +++ b/app/views/admin/budgets/index.html.erb @@ -42,7 +42,7 @@ <% if budget.poll.present? %> - <%= link_to t("admin.budgets.index.admin_ballots"), admin_poll_path(budget.poll) %> + <%= link_to t("admin.budgets.index.admin_ballots"), admin_poll_booth_assignments_path(budget.poll) %> <% else %> <%= link_to_create_budget_poll(budget) %> <% end %> diff --git a/app/views/admin/poll/polls/_subnav.html.erb b/app/views/admin/poll/polls/_subnav.html.erb index 98e23003b..f72176a9e 100644 --- a/app/views/admin/poll/polls/_subnav.html.erb +++ b/app/views/admin/poll/polls/_subnav.html.erb @@ -1,18 +1,20 @@