From 2c3127b6bd74916420cb70e30f39b3e0bf879a9c Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 28 Sep 2016 11:56:19 +0200 Subject: [PATCH] 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" %> @@ -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