From bc92b8d2cd53153994ccc1365acc342354e1810e Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 2 Oct 2017 17:52:13 +0200 Subject: [PATCH 01/28] Update secrets.yml.example file --- config/secrets.yml.example | 74 ++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/config/secrets.yml.example b/config/secrets.yml.example index 6f01d715c..3939d7b80 100644 --- a/config/secrets.yml.example +++ b/config/secrets.yml.example @@ -1,46 +1,74 @@ default: &default - secret_key_base: "56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4" + secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4 + +maps: &maps map_tiles_provider: "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" map_tiles_provider_attribution: "© OpenStreetMap contributors" -development: - <<: *default - -test: - <<: *default - -staging: - server_name: "" - <<: *default - -production: &production - secret_key_base: "817232feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4" - +apis: &apis census_api_end_point: "" census_api_institution_code: "" census_api_portal_name: "" census_api_user_code: "" - sms_end_point: "" sms_username: "" sms_password: "" +http_basic_auth: &http_basic_auth + http_basic_auth: true + + +development: + http_basic_username: "dev" + http_basic_password: "pass" + <<: *default + +test: + <<: *default + <<: *maps + +staging: + secret_key_base: "" + server_name: "" + rollbar_server_token: "" http_basic_username: "" http_basic_password: "" + managers_url: "" + managers_application_key: "" + <<: *default + <<: *maps + <<: *apis +preproduction: + secret_key_base: "" + server_name: "" + rollbar_server_token: "" + http_basic_username: "" + http_basic_password: "" + managers_url: "" + managers_application_key: "" twitter_key: "" twitter_secret: "" facebook_key: "" facebook_secret: "" google_oauth2_key: "" google_oauth2_secret: "" + <<: *maps + <<: *apis +production: + secret_key_base: "" + server_name: "" rollbar_server_token: "" - server_name: "" - - map_tiles_provider: "//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" - map_tiles_provider_attribution: "© OpenStreetMap contributors" - -preproduction: - server_name: "" - <<: *production + http_basic_username: "" + http_basic_password: "" + managers_url: "" + managers_application_key: "" + twitter_key: "" + twitter_secret: "" + facebook_key: "" + facebook_secret: "" + google_oauth2_key: "" + google_oauth2_secret: "" + <<: *maps + <<: *apis From 92605613322f043ab57f6f042d9760d1c986db9b Mon Sep 17 00:00:00 2001 From: Bertocq Date: Mon, 2 Oct 2017 17:55:56 +0200 Subject: [PATCH 02/28] Update deploy secrets example file --- config/deploy-secrets.yml.example | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/config/deploy-secrets.yml.example b/config/deploy-secrets.yml.example index 671263b1c..175026cb1 100644 --- a/config/deploy-secrets.yml.example +++ b/config/deploy-secrets.yml.example @@ -1,25 +1,28 @@ staging: deploy_to: "/var/www/consul" ssh_port: 21 - server: staging.consul.es - user: xxxxx - full_app_name: consul - server_name: staging.consul.es - db_server: postgre.consul.es + server: "staging.consul.es" + db_server: "postgre.consul.es" + user: "xxxxx" + server_name: "staging.consul.es" + full_app_name: "consul" preproduction: deploy_to: "/var/www/consul" ssh_port: 2222 server1: xxx.xxx.xxx.xxx server2: xxx.xxx.xxx.xxx - user: xxxxx - full_app_name: consul db_server: xxx.xxx.xxx.xxx + user: xxxxx + server_name: pre.consul.es + full_app_name: "consul" production: deploy_to: "/var/www/consul" - ssh_port: 2222 - server: xxx.xxx.xxx.xxx - user: xxxxx - full_app_name: consul - + ssh_port: 22 + server1: xxx.xxx.xxx.xxx + server2: xxx.xxx.xxx.xxx + db_server: xxx.xxx.xxx.xxx + user: "deploy" + server_name: "consul.es" + full_app_name: "consul" From 15039b6c5d70abaeee99a416f2a08c88cb853599 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Wed, 4 Oct 2017 11:02:09 +0200 Subject: [PATCH 03/28] Load the Booth polls instead of all current/incoming on Shift creation for date ranges --- app/controllers/admin/poll/shifts_controller.rb | 5 ----- app/views/admin/poll/shifts/_form.html.erb | 4 ++-- spec/features/admin/poll/shifts_spec.rb | 2 ++ 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/poll/shifts_controller.rb b/app/controllers/admin/poll/shifts_controller.rb index 577e8afad..1a5d23f04 100644 --- a/app/controllers/admin/poll/shifts_controller.rb +++ b/app/controllers/admin/poll/shifts_controller.rb @@ -1,7 +1,6 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController before_action :load_booth - before_action :load_polls before_action :load_officer def new @@ -39,10 +38,6 @@ class Admin::Poll::ShiftsController < Admin::Poll::BaseController @booth = ::Poll::Booth.find(params[:booth_id]) end - def load_polls - @polls = ::Poll.current_or_incoming - end - def load_shifts @shifts = @booth.shifts end diff --git a/app/views/admin/poll/shifts/_form.html.erb b/app/views/admin/poll/shifts/_form.html.erb index 6a70396cb..1a13edf45 100644 --- a/app/views/admin/poll/shifts/_form.html.erb +++ b/app/views/admin/poll/shifts/_form.html.erb @@ -24,12 +24,12 @@
<%= select 'shift[date]', 'vote_collection_date', - options_for_select(shift_vote_collection_dates(@polls)), + options_for_select(shift_vote_collection_dates(@booth.polls)), { prompt: t("admin.poll_shifts.new.select_date"), label: false }, class: 'js-shift-vote-collection-dates' %> <%= select 'shift[date]', 'recount_scrutiny_date', - options_for_select(shift_recount_scrutiny_dates(@polls)), + options_for_select(shift_recount_scrutiny_dates(@booth.polls)), { prompt: t("admin.poll_shifts.new.select_date"), label: false }, class: 'js-shift-recount-scrutiny-dates', diff --git a/spec/features/admin/poll/shifts_spec.rb b/spec/features/admin/poll/shifts_spec.rb index 1804735de..2ac290216 100644 --- a/spec/features/admin/poll/shifts_spec.rb +++ b/spec/features/admin/poll/shifts_spec.rb @@ -31,6 +31,8 @@ feature 'Admin shifts' do end scenario "Create Vote Collection Shift and Recount & Scrutiny Shift on same date", :js do + create(:poll) + create(:poll, :incoming) poll = create(:poll, :current) booth = create(:poll_booth) assignment = create(:poll_booth_assignment, poll: poll, booth: booth) From 2900104a07f2b5b6b8582a3b875a2c668a98a1e9 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Wed, 4 Oct 2017 11:55:39 +0200 Subject: [PATCH 04/28] Show only active polls from the shifts assigned to officer on vote panel --- app/controllers/officing/voters_controller.rb | 3 +- app/models/poll/officer.rb | 1 + app/models/poll/shift.rb | 4 ++ spec/features/officing/voters_spec.rb | 44 +++++++++++++++---- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb index 2c3867416..62713096e 100644 --- a/app/controllers/officing/voters_controller.rb +++ b/app/controllers/officing/voters_controller.rb @@ -3,7 +3,8 @@ class Officing::VotersController < Officing::BaseController def new @user = User.find(params[:id]) - @polls = Poll.answerable_by(@user) + booths = current_user.poll_officer.shifts.current.vote_collection.pluck(:booth_id).uniq + @polls = Poll.current.where(id: Poll::BoothAssignment.where(booth: booths).pluck(:poll_id).uniq) end def create diff --git a/app/models/poll/officer.rb b/app/models/poll/officer.rb index bf4c73c36..384202455 100644 --- a/app/models/poll/officer.rb +++ b/app/models/poll/officer.rb @@ -2,6 +2,7 @@ class Poll class Officer < ActiveRecord::Base belongs_to :user has_many :officer_assignments, class_name: "Poll::OfficerAssignment" + has_many :shifts, class_name: "Poll::Shift" has_many :failed_census_calls, foreign_key: :poll_officer_id validates :user_id, presence: true, uniqueness: true diff --git a/app/models/poll/shift.rb b/app/models/poll/shift.rb index 4edeb26ef..e3cfd2280 100644 --- a/app/models/poll/shift.rb +++ b/app/models/poll/shift.rb @@ -10,6 +10,10 @@ class Poll enum task: { vote_collection: 0, recount_scrutiny: 1 } + scope :vote_collection, -> { where(task: 'vote_collection') } + scope :recount_scrutiny, -> { where(task: 'recount_scrutiny') } + scope :current, -> { where(date: Date.current) } + before_create :persist_data after_create :create_officer_assignments before_destroy :destroy_officer_assignments diff --git a/spec/features/officing/voters_spec.rb b/spec/features/officing/voters_spec.rb index b4127b5b8..7974b2e0a 100644 --- a/spec/features/officing/voters_spec.rb +++ b/spec/features/officing/voters_spec.rb @@ -2,16 +2,19 @@ require 'rails_helper' feature 'Voters' do + let(:poll) { create(:poll, :current) } + let(:booth) { create(:poll_booth) } let(:officer) { create(:poll_officer) } background do login_as(officer.user) create(:geozone, :in_census) + 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) end scenario "Can vote", :js do - poll = create(:poll_officer_assignment, officer: officer).booth_assignment.poll - visit new_officing_residence_path officing_verify_residence @@ -31,15 +34,16 @@ feature 'Voters' do end scenario "Already voted", :js do - poll1 = create(:poll) - poll2 = create(:poll) + poll2 = create(:poll, :current) + booth_assignment = create(:poll_booth_assignment, poll: poll2, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) user = create(:user, :level_two) - voter = create(:poll_voter, poll: poll1, user: user) + voter = create(:poll_voter, poll: poll, user: user) visit new_officing_voter_path(id: voter.user.id) - within("#poll_#{poll1.id}") do + within("#poll_#{poll.id}") do expect(page).to have_content "Has already participated in this poll" expect(page).to_not have_button "Confirm vote" end @@ -52,7 +56,6 @@ feature 'Voters' do scenario "Had already verified his residence, but is not level 2 yet", :js do user = create(:user, residence_verified_at: Time.current, document_type: "1", document_number: "12345678Z") expect(user).to_not be_level_two_verified - poll = create(:poll_officer_assignment, officer: officer).booth_assignment.poll visit new_officing_residence_path officing_verify_residence @@ -61,6 +64,29 @@ feature 'Voters' do expect(page).to have_content poll.name end - #Fix and use answerable_by(user) - xscenario "Display only answerable polls" + scenario "Display only current polls on which officer has a voting shift today", :js do + poll_current = create(:poll, :current) + second_booth = create(:poll_booth) + booth_assignment = create(:poll_booth_assignment, poll: poll_current, booth: second_booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + create(:poll_shift, officer: officer, booth: second_booth, date: Date.current, task: :recount_scrutiny) + create(:poll_shift, officer: officer, booth: second_booth, date: Date.tomorrow, task: :vote_collection) + + poll_expired = create(:poll, :expired) + booth_assignment = create(:poll_booth_assignment, poll: poll_expired, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + poll_incoming = create(:poll, :incoming) + booth_assignment = create(:poll_booth_assignment, poll: poll_incoming, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + visit new_officing_residence_path + officing_verify_residence + + expect(page).to have_content "Polls" + expect(page).to have_content poll.name + expect(page).not_to have_content poll_current.name + expect(page).not_to have_content poll_expired.name + expect(page).not_to have_content poll_incoming.name + end end From 4035097c60164b38ecdc408c2ef9f499339f09fe Mon Sep 17 00:00:00 2001 From: iagirre Date: Wed, 4 Oct 2017 16:43:35 +0200 Subject: [PATCH 05/28] Specs added for branch polls-show in consul and thumbnail for poll images in admins views. Cambios para hacer commit: modificado: app/views/images/_admin_image.html.erb modificado: spec/features/admin/poll/polls_spec.rb modificado: spec/features/polls/polls_spec.rb --- app/views/images/_admin_image.html.erb | 9 ++------- spec/features/admin/poll/polls_spec.rb | 4 ++++ spec/features/polls/polls_spec.rb | 8 +++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/views/images/_admin_image.html.erb b/app/views/images/_admin_image.html.erb index a782b743b..12874137f 100644 --- a/app/views/images/_admin_image.html.erb +++ b/app/views/images/_admin_image.html.erb @@ -2,7 +2,6 @@
<%= f.label :image, t("images.form.admin_title") %> - <%= link_to_add_association t('images.form.add_new_image'), f, :image, force_non_association_create: true, partial: "images/image_fields", @@ -15,6 +14,8 @@ association_insertion_node: "#nested-image", association_insertion_method: "append" } %> + + <%= render_image(f.object.image, :thumb, false) if f.object.image %>
<%= f.fields_for :image do |image_builder| %> @@ -26,17 +27,11 @@ <%= image_builder.text_field :title, placeholder: t("images.form.title_placeholder"), label: "#{t("images.form.admin_alt_text")}" %> -
<%= render_image_attachment(image_builder, imageable, image_builder.object) %>
- -
-
-
-
<% end %> diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index be987df2d..d69e7ad75 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -70,14 +70,18 @@ feature 'Admin polls' do scenario "Edit" do poll = create(:poll) + create(:image, imageable: poll) visit admin_poll_path(poll) click_link "Edit" end_date = 1.year.from_now + expect(page).to have_css("img[alt='#{poll.image.title}']") + 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" diff --git a/spec/features/polls/polls_spec.rb b/spec/features/polls/polls_spec.rb index 8a90fb4a8..90645b6ac 100644 --- a/spec/features/polls/polls_spec.rb +++ b/spec/features/polls/polls_spec.rb @@ -6,11 +6,15 @@ feature 'Polls' do scenario 'Polls can be listed' do polls = create_list(:poll, 3) + create(:image, imageable: polls[0]) + create(:image, imageable: polls[1]) + create(:image, imageable: polls[2]) visit polls_path polls.each do |poll| expect(page).to have_content(poll.name) + expect(page).to have_css("img[alt='#{poll.image.title}']") expect(page).to have_link("Participate in this poll") end end @@ -59,7 +63,7 @@ feature 'Polls' do context 'Show' do let(:geozone) { create(:geozone) } - let(:poll) { create(:poll) } + let(:poll) { create(:poll, summary: "Summary", description: "Description") } scenario 'Lists questions from proposals as well as regular ones' do normal_question = create(:poll_question, poll: poll) @@ -67,6 +71,8 @@ feature 'Polls' do visit poll_path(poll) expect(page).to have_content(poll.name) + expect(page).to have_content(poll.summary) + expect(page).to have_content(poll.description) expect(page).to have_content(normal_question.title) expect(page).to have_content(proposal_question.title) From 24ef7984a3e042c03756d76fd41c93b9b529aef2 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Wed, 4 Oct 2017 17:05:25 +0200 Subject: [PATCH 06/28] Include the answerable by user scope back on Poll list for officer voting panel --- app/controllers/officing/voters_controller.rb | 2 +- spec/features/officing/voters_spec.rb | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/app/controllers/officing/voters_controller.rb b/app/controllers/officing/voters_controller.rb index 62713096e..2b7ed329f 100644 --- a/app/controllers/officing/voters_controller.rb +++ b/app/controllers/officing/voters_controller.rb @@ -4,7 +4,7 @@ class Officing::VotersController < Officing::BaseController def new @user = User.find(params[:id]) booths = current_user.poll_officer.shifts.current.vote_collection.pluck(:booth_id).uniq - @polls = Poll.current.where(id: Poll::BoothAssignment.where(booth: booths).pluck(:poll_id).uniq) + @polls = Poll.answerable_by(@user).where(id: Poll::BoothAssignment.where(booth: booths).pluck(:poll_id).uniq) end def create diff --git a/spec/features/officing/voters_spec.rb b/spec/features/officing/voters_spec.rb index 7974b2e0a..2c4b17d37 100644 --- a/spec/features/officing/voters_spec.rb +++ b/spec/features/officing/voters_spec.rb @@ -64,7 +64,7 @@ feature 'Voters' do expect(page).to have_content poll.name end - scenario "Display only current polls on which officer has a voting shift today", :js do + scenario "Display only current polls on which officer has a voting shift today, and user can answer", :js do poll_current = create(:poll, :current) second_booth = create(:poll_booth) booth_assignment = create(:poll_booth_assignment, poll: poll_current, booth: second_booth) @@ -73,11 +73,17 @@ feature 'Voters' do create(:poll_shift, officer: officer, booth: second_booth, date: Date.tomorrow, task: :vote_collection) poll_expired = create(:poll, :expired) - booth_assignment = create(:poll_booth_assignment, poll: poll_expired, booth: booth) - create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + create(:poll_officer_assignment, officer: officer, booth_assignment: create(:poll_booth_assignment, poll: poll_expired, booth: booth)) poll_incoming = create(:poll, :incoming) - booth_assignment = create(:poll_booth_assignment, poll: poll_incoming, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: create(:poll_booth_assignment, poll: poll_incoming, booth: booth)) + + poll_geozone_restricted_in = create(:poll, :current, geozone_restricted: true, geozones: [Geozone.first]) + booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_in, booth: booth) + create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) + + poll_geozone_restricted_out = create(:poll, :current, geozone_restricted: true, geozones: [create(:geozone, census_code: "02")]) + booth_assignment = create(:poll_booth_assignment, poll: poll_geozone_restricted_out, booth: booth) create(:poll_officer_assignment, officer: officer, booth_assignment: booth_assignment) visit new_officing_residence_path @@ -88,5 +94,7 @@ feature 'Voters' do expect(page).not_to have_content poll_current.name expect(page).not_to have_content poll_expired.name expect(page).not_to have_content poll_incoming.name + expect(page).to have_content poll_geozone_restricted_in.name + expect(page).not_to have_content poll_geozone_restricted_out.name end end From c62b573489e3c36fe0b8f2597c2229ba06fb01c6 Mon Sep 17 00:00:00 2001 From: Bertocq Date: Wed, 4 Oct 2017 17:59:29 +0200 Subject: [PATCH 07/28] Fix poll Voter feature spec --- spec/features/polls/voter_spec.rb | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/spec/features/polls/voter_spec.rb b/spec/features/polls/voter_spec.rb index d925d3394..bd4a57298 100644 --- a/spec/features/polls/voter_spec.rb +++ b/spec/features/polls/voter_spec.rb @@ -4,8 +4,18 @@ feature "Voter" do context "Origin" do + let(:poll) { create(:poll, :current) } + let(:booth) { create(:poll_booth) } + let(:officer) { create(:poll_officer) } + + background do + create(:geozone, :in_census) + 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) + end + scenario "Voting via web", :js do - poll = create(:poll) question = create(:poll_question, poll: poll, valid_answers: 'Yes, No') user = create(:user, :level_two) @@ -22,14 +32,7 @@ feature "Voter" do end scenario "Voting in booth", :js do - user = create(:user, :in_census) - create(:geozone, :in_census) - - poll = create(:poll) - officer = create(:poll_officer) - - ba = create(:poll_booth_assignment, poll: poll) - create(:poll_officer_assignment, officer: officer, booth_assignment: ba) + user = create(:user, :in_census) login_through_form_as_officer(officer.user) @@ -47,14 +50,9 @@ feature "Voter" do context "Trying to vote the same poll in booth and web" do - let(:poll) { create(:poll) } let(:question) { create(:poll_question, poll: poll, valid_answers: 'Yes, No') } let!(:user) { create(:user, :in_census) } - let(:officer) { create(:poll_officer) } - let(:ba) { create(:poll_booth_assignment, poll: poll) } - let!(:oa) { create(:poll_officer_assignment, officer: officer, booth_assignment: ba) } - scenario "Trying to vote in web and then in booth", :js do login_as user vote_for_poll_via_web(poll, question) From 3ae539e8ab1a4edde32f0ec964c60ccaef305423 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 4 Oct 2017 20:10:31 +0200 Subject: [PATCH 08/28] fixes relation between questions and answers --- app/controllers/admin/poll/questions/answers_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/poll/questions/answers_controller.rb b/app/controllers/admin/poll/questions/answers_controller.rb index d0a7c4cc7..660339844 100644 --- a/app/controllers/admin/poll/questions/answers_controller.rb +++ b/app/controllers/admin/poll/questions/answers_controller.rb @@ -21,7 +21,7 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController private def answer_params - params.require(:poll_question_answer).permit(:title, :description, :poll_question_id) + params.require(:poll_question_answer).permit(:title, :description, :question_id) end def load_question From 24fc7ab70aabd76d0479b95194c729d4740a3adf Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 4 Oct 2017 20:10:49 +0200 Subject: [PATCH 09/28] makes answer creation spec more robust --- spec/features/polls/answers_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb index 5b1091134..79f045500 100644 --- a/spec/features/polls/answers_spec.rb +++ b/spec/features/polls/answers_spec.rb @@ -33,6 +33,10 @@ feature 'Answers' do click_button "Save" expect(page).to have_content "Answer created successfully" + + expect(page).to have_css(".poll_question_answer", count: 1) + expect(page).to have_content "¿Would you like to reform Central Park?" + expect(page).to have_content "Adding more trees, creating a play area..." end pending "Update" From 1cf9bc4ad134fa000256affa937bc67d975963b6 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 4 Oct 2017 21:42:57 +0200 Subject: [PATCH 10/28] adds images to anwers --- .../questions/answers/images_controller.rb | 33 ++++++++++ app/models/concerns/galleryable.rb | 12 ++++ app/models/direct_upload.rb | 5 +- app/models/poll/question/answer.rb | 2 + .../questions/answers/images/index.html.erb | 9 +++ .../questions/answers/images/new.html.erb | 66 +++++++++++++++++++ app/views/admin/poll/questions/show.html.erb | 5 ++ config/routes.rb | 5 +- .../questions/answers/images/images_spec.rb | 31 +++++++++ spec/shared/features/nested_imageable.rb | 1 + 10 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 app/controllers/admin/poll/questions/answers/images_controller.rb create mode 100644 app/models/concerns/galleryable.rb create mode 100644 app/views/admin/poll/questions/answers/images/index.html.erb create mode 100644 app/views/admin/poll/questions/answers/images/new.html.erb create mode 100644 spec/features/admin/poll/questions/answers/images/images_spec.rb diff --git a/app/controllers/admin/poll/questions/answers/images_controller.rb b/app/controllers/admin/poll/questions/answers/images_controller.rb new file mode 100644 index 000000000..39ff5100d --- /dev/null +++ b/app/controllers/admin/poll/questions/answers/images_controller.rb @@ -0,0 +1,33 @@ +class Admin::Poll::Questions::Answers::ImagesController < Admin::Poll::BaseController + before_action :load_answer + + def index + end + + def new + @answer = ::Poll::Question::Answer.find(params[:answer_id]) + end + + def create + @answer = ::Poll::Question::Answer.find(params[:answer_id]) + @answer.attributes = images_params + + if @answer.save + redirect_to admin_answer_images_path(@answer), + notice: "Image uploaded successfully" + else + render :new + end + end + + private + + def images_params + params.require(:poll_question_answer) + .permit(images_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy]) + end + + def load_answer + @answer = ::Poll::Question::Answer.find(params[:answer_id]) + end +end diff --git a/app/models/concerns/galleryable.rb b/app/models/concerns/galleryable.rb new file mode 100644 index 000000000..1063c5571 --- /dev/null +++ b/app/models/concerns/galleryable.rb @@ -0,0 +1,12 @@ +module Galleryable + extend ActiveSupport::Concern + + included do + has_many :images, as: :imageable, dependent: :destroy + accepts_nested_attributes_for :images, allow_destroy: true, update_only: true + + def image_url(style) + image.attachment.url(style) if image && image.attachment.exists? + end + end +end \ No newline at end of file diff --git a/app/models/direct_upload.rb b/app/models/direct_upload.rb index a6b6ef276..348c2641e 100644 --- a/app/models/direct_upload.rb +++ b/app/models/direct_upload.rb @@ -19,8 +19,9 @@ class DirectUpload if @resource_type.present? && @resource_relation.present? && (@attachment.present? || @cached_attachment.present?) @resource = @resource_type.constantize.find_or_initialize_by(id: @resource_id) - if @resource.class.reflections[@resource_relation].macro == :has_one - @relation = @resource.send("build_#{resource_relation}", relation_attributtes) + if true #@resource.class.reflections[@resource_relation].macro == :has_one + #@relation = @resource.send("build_#{resource_relation}", relation_attributtes) + @relation = @resource.images.send("build", relation_attributtes) else @relation = @resource.send(@resource_relation).build(relation_attributtes) end diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index 3f8f4a172..1746c480c 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -1,4 +1,6 @@ class Poll::Question::Answer < ActiveRecord::Base + include Galleryable + belongs_to :question, class_name: 'Poll::Question', foreign_key: 'question_id' validates :title, presence: true diff --git a/app/views/admin/poll/questions/answers/images/index.html.erb b/app/views/admin/poll/questions/answers/images/index.html.erb new file mode 100644 index 000000000..09d055783 --- /dev/null +++ b/app/views/admin/poll/questions/answers/images/index.html.erb @@ -0,0 +1,9 @@ +<%= back_link_to admin_question_path(@answer.question) %> + +<% @answer.images.each do |image| %> + <%= render_image(image, :large, true) if image.present? %> +<% end %> + +
+ <%= link_to "Add image", new_admin_answer_image_path(@answer) %> +
\ No newline at end of file diff --git a/app/views/admin/poll/questions/answers/images/new.html.erb b/app/views/admin/poll/questions/answers/images/new.html.erb new file mode 100644 index 000000000..17e728a21 --- /dev/null +++ b/app/views/admin/poll/questions/answers/images/new.html.erb @@ -0,0 +1,66 @@ +<%= form_for(Poll::Question::Answer.new, + url: admin_answer_images_path(@answer), + method: :post) do |f| %> +
+ <%# render 'images/nested_image', imageable: @answer, f: f %> + + <%= f.label :images, t("images.form.title") %> +
+ +

<%# imageables_note(imageable) %>

+ +
+ <%= f.fields_for :images do |image_builder| %> + <%# render 'images/image_fields', f: image_builder, imageable: imageable %> +
+ <%= f.hidden_field :id %> + <%= f.hidden_field :user_id, value: current_user.id %> + <%= f.hidden_field :cached_attachment %> + +
+ <%= f.text_field :title, placeholder: t("images.form.title_placeholder") %> +
+ + <%= render_image(f.object, :thumb, false) if f.object.attachment.exists? %> + +
+
+ <%= render_image_attachment(f, @answer, f.object) %> +
+
+ <%= render_destroy_image_link(f, f.object) %> +
+
+ +
+

+ <%= image_attachment_file_name(f.object) %> +

+
+ +
+
+
+ +
+
+ <% end %> +
+ + <%= link_to_add_association t('images.form.add_new_image'), f, :images, + force_non_association_create: true, + partial: "images/image_fields", + id: "new_image_link", + class: "button hollow #{"hide" if @answer.images.present?}", + render_options: { + locals: { imageable: @answer } + }, + data: { + association_insertion_node: "#nested-image", + association_insertion_method: "append" + } %> + +
+ + <%= f.submit "Save image" %> +<% end %> \ 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 7037afd5f..024c30cd5 100644 --- a/app/views/admin/poll/questions/show.html.erb +++ b/app/views/admin/poll/questions/show.html.erb @@ -39,12 +39,17 @@ <%= t("admin.questions.show.answers.title") %> <%= t("admin.questions.show.answers.description") %> + Imágenes <% @question.question_answers.each do |answer| %> <%= answer.title %> <%= answer.description %> + + <%= link_to "Lista de imágenes", + admin_answer_images_path(answer) %> + <% end %> diff --git a/config/routes.rb b/config/routes.rb index 89691feac..387983d4b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -301,7 +301,10 @@ Rails.application.routes.draw do end resources :questions do - resources :answers, only: [:new, :create], controller: 'questions/answers' + resources :answers, only: [:new, :create], controller: 'questions/answers', shallow: true do + resources :images, controller: 'questions/answers/images' + end + end end diff --git a/spec/features/admin/poll/questions/answers/images/images_spec.rb b/spec/features/admin/poll/questions/answers/images/images_spec.rb new file mode 100644 index 000000000..54cd0544b --- /dev/null +++ b/spec/features/admin/poll/questions/answers/images/images_spec.rb @@ -0,0 +1,31 @@ +require 'rails_helper' + +feature 'Images' do + + background do + admin = create(:administrator) + login_as(admin.user) + end + + scenario "Index" do + end + + scenario "Create", :js do + question = create(:poll_question) + answer = create(:poll_question_answer, question: question) + + visit admin_question_path(question) + + within("#poll_question_answer_#{answer.id}") do + click_link "Lista de imágenes" + end + + click_link "Add image" + + imageable_attach_new_file(:poll_question_answer, "spec/fixtures/files/clippy.jpg") + click_button "Save image" + + expect(page).to have_content "Image uploaded successfully" + end + +end \ No newline at end of file diff --git a/spec/shared/features/nested_imageable.rb b/spec/shared/features/nested_imageable.rb index 242686bd6..68aab3a92 100644 --- a/spec/shared/features/nested_imageable.rb +++ b/spec/shared/features/nested_imageable.rb @@ -214,6 +214,7 @@ end def imageable_attach_new_file(imageable_factory_name, path, success = true) click_link "Add image" + within "#nested-image" do image = find(".image") image_input = image.find("input[type=file]", visible: false) From 30a2db635dbba22bbe7ca0df4f53f565043b06a4 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 4 Oct 2017 22:47:09 +0200 Subject: [PATCH 11/28] displays upload link for second image To infinity and beyond --- app/views/admin/poll/questions/answers/images/new.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/poll/questions/answers/images/new.html.erb b/app/views/admin/poll/questions/answers/images/new.html.erb index 17e728a21..14156a79d 100644 --- a/app/views/admin/poll/questions/answers/images/new.html.erb +++ b/app/views/admin/poll/questions/answers/images/new.html.erb @@ -51,7 +51,7 @@ force_non_association_create: true, partial: "images/image_fields", id: "new_image_link", - class: "button hollow #{"hide" if @answer.images.present?}", + class: "button hollow", render_options: { locals: { imageable: @answer } }, From 06a1b96fcd631d059c869817469e646eadf67e6b Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 4 Oct 2017 22:55:28 +0200 Subject: [PATCH 12/28] clean up --- app/models/direct_upload.rb | 5 +- .../questions/answers/images/index.html.erb | 8 +-- .../questions/answers/images/new.html.erb | 60 +------------------ app/views/images/_nested_image.html.erb | 11 ++-- 4 files changed, 16 insertions(+), 68 deletions(-) diff --git a/app/models/direct_upload.rb b/app/models/direct_upload.rb index 348c2641e..192f06d04 100644 --- a/app/models/direct_upload.rb +++ b/app/models/direct_upload.rb @@ -19,9 +19,10 @@ class DirectUpload if @resource_type.present? && @resource_relation.present? && (@attachment.present? || @cached_attachment.present?) @resource = @resource_type.constantize.find_or_initialize_by(id: @resource_id) - if true #@resource.class.reflections[@resource_relation].macro == :has_one - #@relation = @resource.send("build_#{resource_relation}", relation_attributtes) + if @resource.respond_to?(:images) @relation = @resource.images.send("build", relation_attributtes) + elsif @resource.class.reflections[@resource_relation].macro == :has_one + @relation = @resource.send("build_#{resource_relation}", relation_attributtes) else @relation = @resource.send(@resource_relation).build(relation_attributtes) end diff --git a/app/views/admin/poll/questions/answers/images/index.html.erb b/app/views/admin/poll/questions/answers/images/index.html.erb index 09d055783..79333b660 100644 --- a/app/views/admin/poll/questions/answers/images/index.html.erb +++ b/app/views/admin/poll/questions/answers/images/index.html.erb @@ -1,9 +1,9 @@ <%= back_link_to admin_question_path(@answer.question) %> +
+ <%= link_to "Add image", new_admin_answer_image_path(@answer) %> +
+ <% @answer.images.each do |image| %> <%= render_image(image, :large, true) if image.present? %> <% end %> - -
- <%= link_to "Add image", new_admin_answer_image_path(@answer) %> -
\ No newline at end of file diff --git a/app/views/admin/poll/questions/answers/images/new.html.erb b/app/views/admin/poll/questions/answers/images/new.html.erb index 14156a79d..80126bef7 100644 --- a/app/views/admin/poll/questions/answers/images/new.html.erb +++ b/app/views/admin/poll/questions/answers/images/new.html.erb @@ -1,66 +1,10 @@ <%= form_for(Poll::Question::Answer.new, url: admin_answer_images_path(@answer), method: :post) do |f| %> +
- <%# render 'images/nested_image', imageable: @answer, f: f %> - - <%= f.label :images, t("images.form.title") %> + <%= render 'images/nested_image', imageable: @answer, f: f, image_fields: :images %>
-

<%# imageables_note(imageable) %>

- -
- <%= f.fields_for :images do |image_builder| %> - <%# render 'images/image_fields', f: image_builder, imageable: imageable %> -
- <%= f.hidden_field :id %> - <%= f.hidden_field :user_id, value: current_user.id %> - <%= f.hidden_field :cached_attachment %> - -
- <%= f.text_field :title, placeholder: t("images.form.title_placeholder") %> -
- - <%= render_image(f.object, :thumb, false) if f.object.attachment.exists? %> - -
-
- <%= render_image_attachment(f, @answer, f.object) %> -
-
- <%= render_destroy_image_link(f, f.object) %> -
-
- -
-

- <%= image_attachment_file_name(f.object) %> -

-
- -
-
-
- -
-
- <% end %> -
- - <%= link_to_add_association t('images.form.add_new_image'), f, :images, - force_non_association_create: true, - partial: "images/image_fields", - id: "new_image_link", - class: "button hollow", - render_options: { - locals: { imageable: @answer } - }, - data: { - association_insertion_node: "#nested-image", - association_insertion_method: "append" - } %> - -
- <%= f.submit "Save image" %> <% end %> \ No newline at end of file diff --git a/app/views/images/_nested_image.html.erb b/app/views/images/_nested_image.html.erb index 2f65b8760..ff9e3d242 100644 --- a/app/views/images/_nested_image.html.erb +++ b/app/views/images/_nested_image.html.erb @@ -1,17 +1,20 @@ -<%= f.label :image, t("images.form.title") %> +<%= image_fields ||= :image %> + +<%= f.label image_fields, t("images.form.title") %>

<%= imageables_note(imageable) %>

- <%= f.fields_for :image do |image_builder| %> + <%= f.fields_for image_fields do |image_builder| %> <%= render 'images/image_fields', f: image_builder, imageable: imageable %> <% end %>
-<%= link_to_add_association t('images.form.add_new_image'), f, :image, +<%= link_to_add_association t('images.form.add_new_image'), f, image_fields, force_non_association_create: true, partial: "images/image_fields", id: "new_image_link", - class: "button hollow #{"hide" if imageable.image.present?}", + class: "button hollow + #{"hide" if image_fields == :image && imageable.image.present?}", render_options: { locals: { imageable: imageable } }, From bba8cac2625655dbea15cb9c948d844ee8e10d63 Mon Sep 17 00:00:00 2001 From: rgarcia Date: Wed, 4 Oct 2017 23:55:45 +0200 Subject: [PATCH 13/28] displays images for an answer --- app/views/polls/_gallery.html.erb | 28 +++++++++++--------------- app/views/polls/show.html.erb | 33 ++++++++++++++++--------------- 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/app/views/polls/_gallery.html.erb b/app/views/polls/_gallery.html.erb index 3354c4de7..86f8f0d4d 100644 --- a/app/views/polls/_gallery.html.erb +++ b/app/views/polls/_gallery.html.erb @@ -15,22 +15,18 @@ <%= t("shared.orbit.next_slide") %>▶︎ - -
  • - <%= link_to "/assets/example_vertical.jpg", target: "_blank" do %> - <%= image_tag "example_horizontal.jpg", class: "orbit-image" %> - <% end %> - - Image title 1 - -
  • - -
  • - <%= link_to "/assets/example_vertical.jpg", target: "_blank" do %> - <%= image_tag "example_vertical.jpg", class: "orbit-image" %> - <% end %> - Image title 2 -
  • + + <% answer.images.each do |image| %> +
  • + <%= link_to image.attachment.url(:original), target: "_blank" do %> + <%= image_tag image.attachment.url(:medium), + class: "orbit-image", + alt: image.title %> + <% end %> + <%= image.title %> +
  • + <% end %> +