diff --git a/app/controllers/management/proposals_controller.rb b/app/controllers/management/proposals_controller.rb new file mode 100644 index 000000000..8ae63e94e --- /dev/null +++ b/app/controllers/management/proposals_controller.rb @@ -0,0 +1,52 @@ +class Management::ProposalsController < Management::BaseController + include HasOrders + include CommentableActions + + before_action :check_verified_user, except: :print + before_action :set_proposal, only: :vote + before_action :parse_search_terms, only: :index + + has_orders %w{hot_score confidence_score created_at most_commented random}, only: [:index, :print] + + def vote + @proposal.register_vote(current_user, 'yes') + set_proposal_votes(@proposal) + end + + def print + @proposals = Proposal.all.page(params[:page]).for_render.send("sort_by_#{@current_order}") + set_proposal_votes(@proposal) + end + + private + + def set_proposal + @proposal = Proposal.find(params[:id]) + end + + def proposal_params + params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url, :responsible_name, :tag_list, :terms_of_service, :captcha, :captcha_key) + end + + def current_user + #CHANGE ME + #Should be user being managed + User.last + end + + def resource_model + Proposal + end + + def check_verified_user + unless current_user.level_two_or_three_verified? + redirect_to management_root_path, alert: t("management.proposals.alert.unverified_user") + end + end + + #Duplicated in application_controller. Move to a concenrn. + def set_proposal_votes(proposals) + @proposal_votes = current_user ? current_user.proposal_votes(proposals) : {} + end + +end \ No newline at end of file diff --git a/app/views/admin/shared/_proposal_search.html.erb b/app/views/admin/shared/_proposal_search.html.erb new file mode 100644 index 000000000..9604edf34 --- /dev/null +++ b/app/views/admin/shared/_proposal_search.html.erb @@ -0,0 +1,10 @@ +<%= form_for(Proposal.new, url: url, as: :proposal, method: :get) do |f| %> +
+
+ <%= text_field_tag :search, "", placeholder: t("admin.shared.proposal_search.placeholder") %> +
+
+ <%= f.submit t("admin.shared.proposal_search.button"), class: "button radius success" %> +
+
+<% end %> \ No newline at end of file diff --git a/app/views/management/proposals/_proposal.html.erb b/app/views/management/proposals/_proposal.html.erb new file mode 100644 index 000000000..be7a2e6b2 --- /dev/null +++ b/app/views/management/proposals/_proposal.html.erb @@ -0,0 +1 @@ +<%= render partial: 'proposals/proposal', locals: {proposal: proposal} %> \ No newline at end of file diff --git a/app/views/management/proposals/_votes.html.erb b/app/views/management/proposals/_votes.html.erb new file mode 100644 index 000000000..922c3e383 --- /dev/null +++ b/app/views/management/proposals/_votes.html.erb @@ -0,0 +1,2 @@ +<%= render 'proposals/votes', + { proposal: proposal, vote_url: vote_management_proposal_path(proposal, value: 'yes') } %> \ No newline at end of file diff --git a/app/views/management/proposals/index.html.erb b/app/views/management/proposals/index.html.erb new file mode 100644 index 000000000..f6044265c --- /dev/null +++ b/app/views/management/proposals/index.html.erb @@ -0,0 +1,22 @@ +
+ <%= render 'admin/shared/proposal_search', url: management_proposals_path %> + +
+
+ +
+
+ <% if @search_terms %> +

+ <%= page_entries_info @proposals %> + <%= t("proposals.index.search_results", count: @proposals.size, search_term: @search_terms) %> +

+ <% end %> +
+ + <%= render @proposals %> + <%= paginate @proposals %> +
+
+
+
\ No newline at end of file diff --git a/app/views/management/proposals/new.html.erb b/app/views/management/proposals/new.html.erb new file mode 100644 index 000000000..3586594f6 --- /dev/null +++ b/app/views/management/proposals/new.html.erb @@ -0,0 +1,7 @@ +
+ +
+ <%= render "proposals/form", form_url: management_proposals_url %> +
+ +
diff --git a/app/views/management/proposals/print.html.erb b/app/views/management/proposals/print.html.erb new file mode 100644 index 000000000..9fd1c50cb --- /dev/null +++ b/app/views/management/proposals/print.html.erb @@ -0,0 +1,35 @@ +
+ + <%= t('management.proposals.print.print_button') %> + +
+
+ +
+
+
+

+ <%= t("proposals.index.select_order_long") %> +

+ <%= render 'shared/order_selector', i18n_namespace: "proposals.index" %> +
+
+
+ + <%= render @proposals %> + <%= paginate @proposals %> +
+
+
+ + + \ No newline at end of file diff --git a/app/views/management/proposals/vote.js.erb b/app/views/management/proposals/vote.js.erb new file mode 100644 index 000000000..73b2507c2 --- /dev/null +++ b/app/views/management/proposals/vote.js.erb @@ -0,0 +1 @@ +<%= render template: 'proposals/vote' %> \ No newline at end of file diff --git a/app/views/proposals/_form.html.erb b/app/views/proposals/_form.html.erb index 40b0e5b52..4c14730fe 100644 --- a/app/views/proposals/_form.html.erb +++ b/app/views/proposals/_form.html.erb @@ -1,4 +1,4 @@ -<%= form_for(@proposal) do |f| %> +<%= form_for(@proposal, url: form_url) do |f| %> <%= render 'shared/errors', resource: @proposal %>
diff --git a/app/views/proposals/_proposal.html.erb b/app/views/proposals/_proposal.html.erb index 575722805..c536c897f 100644 --- a/app/views/proposals/_proposal.html.erb +++ b/app/views/proposals/_proposal.html.erb @@ -47,7 +47,8 @@
- <%= render 'proposals/votes', proposal: proposal %> + <%= render 'votes', + { proposal: proposal, vote_url: vote_proposal_path(proposal, value: 'yes') } %>
diff --git a/app/views/proposals/_votes.html.erb b/app/views/proposals/_votes.html.erb index 965f61bf7..b7e7d12a0 100644 --- a/app/views/proposals/_votes.html.erb +++ b/app/views/proposals/_votes.html.erb @@ -22,7 +22,7 @@ <%= t("proposals.proposal.already_supported") %> <% else %> - <%= link_to vote_proposal_path(proposal, value: 'yes'), + <%= link_to vote_url, class: "button button-support tiny radius expand", title: t('proposals.proposal.support_title'), method: "post", remote: true do %> <%= t("proposals.proposal.support") %> diff --git a/app/views/proposals/edit.html.erb b/app/views/proposals/edit.html.erb index 7d7ce413b..1ed03d533 100644 --- a/app/views/proposals/edit.html.erb +++ b/app/views/proposals/edit.html.erb @@ -12,6 +12,6 @@

<%= t("proposals.edit.editing") %>

- <%= render "form" %> + <%= render "form", form_url: proposal_url(@proposal) %> diff --git a/app/views/proposals/index.html.erb b/app/views/proposals/index.html.erb index 28807d247..c0bbdc009 100644 --- a/app/views/proposals/index.html.erb +++ b/app/views/proposals/index.html.erb @@ -44,7 +44,7 @@ <%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %> - <%= render @proposals %> + <%= render partial: 'proposals/proposal', collection: @proposals %> <%= paginate @proposals %> diff --git a/app/views/proposals/new.html.erb b/app/views/proposals/new.html.erb index 0bda9fd56..a24a31e77 100644 --- a/app/views/proposals/new.html.erb +++ b/app/views/proposals/new.html.erb @@ -11,7 +11,7 @@ <%= t("proposals.new.more_info")%> <% end %> - <%= render "form" %> + <%= render "proposals/form", form_url: proposals_url %>
diff --git a/app/views/proposals/show.html.erb b/app/views/proposals/show.html.erb index 119968e4d..b72d7c7d5 100644 --- a/app/views/proposals/show.html.erb +++ b/app/views/proposals/show.html.erb @@ -97,7 +97,8 @@

<%= t("votes.supports") %>

- <%= render 'proposals/votes', proposal: @proposal %> + <%= render 'votes', + { proposal: @proposal, vote_url: vote_proposal_path(@proposal, value: 'yes') } %>
diff --git a/app/views/welcome/_votes.html.erb b/app/views/welcome/_votes.html.erb new file mode 100644 index 000000000..4419a0b12 --- /dev/null +++ b/app/views/welcome/_votes.html.erb @@ -0,0 +1,2 @@ +<%= render 'proposals/votes', + { proposal: proposal, vote_url: vote_proposal_path(proposal, value: 'yes') } %> \ No newline at end of file diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml index d298f8250..a70329132 100644 --- a/config/locales/admin.en.yml +++ b/config/locales/admin.en.yml @@ -26,6 +26,9 @@ en: user_search: placeholder: 'Search user by name or email' button: 'Search' + proposal_search: + placeholder: 'Search proposals by title, description or question' + button: 'Search' organizations: index: title: Organizations diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml index b9845c21e..40aef5f24 100644 --- a/config/locales/admin.es.yml +++ b/config/locales/admin.es.yml @@ -26,6 +26,9 @@ es: user_search: placeholder: 'Buscar usuario por nombre o email' button: 'Buscar' + proposal_search: + placeholder: 'Buscar propuestas por título, descripción o pregunta' + button: 'Buscar' organizations: index: title: Organizaciones diff --git a/config/locales/management.en.yml b/config/locales/management.en.yml index 5cc0f0bb7..d9ea82a46 100644 --- a/config/locales/management.en.yml +++ b/config/locales/management.en.yml @@ -12,6 +12,11 @@ en: dashboard: index: title: "Management" + proposals: + print: + print_button: Print + alert: + unverified_user: User is not verified permissions: debates: "Engage in debates" create_proposals: "Create proposals" diff --git a/config/locales/management.es.yml b/config/locales/management.es.yml index 2b91730db..913098e36 100644 --- a/config/locales/management.es.yml +++ b/config/locales/management.es.yml @@ -11,7 +11,12 @@ es: users: "Usuarios" dashboard: index: - title: "Gestión" + title: "Gestión" + proposals: + print: + print_button: Imprimir + alert: + unverified_user: Este usuario no está verificado permissions: debates: "Participar en debates" create_proposals: "Crear nuevas propuestas" diff --git a/config/routes.rb b/config/routes.rb index 1b1187c90..ed91d1f07 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -185,6 +185,15 @@ Rails.application.routes.draw do get 'sign_in', to: 'sessions#create' resources :sessions, only: :create + resources :proposals, only: [:index, :new, :create] do + member do + post :vote + end + + collection do + get :print + end + end end # Example of regular route: diff --git a/spec/features/management/proposals_spec.rb b/spec/features/management/proposals_spec.rb new file mode 100644 index 000000000..571c07ec8 --- /dev/null +++ b/spec/features/management/proposals_spec.rb @@ -0,0 +1,141 @@ +require 'rails_helper' + +feature 'Proposals' do + + background do + manager = create(:manager) + login_as_manager(manager) + end + + context "Create" do + + scenario 'Creating proposals on behalf of someone' do + user = create(:user, :level_two) + login_managed_user(user) + + visit new_management_proposal_path + + fill_in 'proposal_title', with: 'Help refugees' + fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' + fill_in 'proposal_summary', with: 'In summary, what we want is...' + fill_in 'proposal_description', with: 'This is very important because...' + fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' + fill_in 'proposal_video_url', with: 'http://youtube.com' + fill_in 'proposal_captcha', with: correct_captcha_text + check 'proposal_terms_of_service' + + click_button 'Start a proposal' + + expect(page).to have_content 'Proposal was successfully created.' + + expect(page).to have_content 'Help refugees' + expect(page).to have_content '¿Would you like to give assistance to war refugees?' + expect(page).to have_content 'In summary, what we want is...' + expect(page).to have_content 'This is very important because...' + expect(page).to have_content 'http://rescue.org/refugees' + expect(page).to have_content 'http://youtube.com' + expect(page).to have_content user.name + expect(page).to have_content I18n.l(Proposal.last.created_at.to_date) + end + + scenario "Should not allow unverified users to create proposals" do + user = create(:user) + login_managed_user(user) + + visit new_management_proposal_path + + expect(page).to have_content "User is not verified" + end + end + + context "Voting" do + + scenario 'Voting proposals on behalf of someone', :js do + proposal = create(:proposal) + + user = create(:user, :level_two) + login_managed_user(user) + + visit management_proposals_path + + within("#proposals") do + find('.in-favor a').click + + expect(page).to have_content "1 support" + expect(page).to have_content "You already supported this proposal" + end + expect(URI.parse(current_url).path).to eq(management_proposals_path) + end + + scenario "Should not allow unverified users to vote proposals" do + proposal = create(:proposal) + + user = create(:user) + login_managed_user(user) + + visit management_proposals_path + + expect(page).to have_content "User is not verified" + end + + scenario "Searching" do + proposal1 = create(:proposal, title: "Show me what you got") + proposal2 = create(:proposal, title: "Get Schwifty") + + user = create(:user, :level_two) + login_managed_user(user) + + visit management_proposals_path + + fill_in "search", with: "what you got" + click_button "Search" + + expect(current_path).to eq(management_proposals_path) + + within("#proposals") do + expect(page).to have_css('.proposal', count: 1) + expect(page).to have_content(proposal1.title) + expect(page).to_not have_content(proposal2.title) + end + end + end + + context "Printing" do + scenario 'Printing proposals', :js do + 5.times { create(:proposal) } + + visit print_management_proposals_path + + find("#print_link").click + + ### CHANGE ME + # should probably test something else here + # maybe that we are loading a print.css stylesheet? + ### + end + + scenario "Filtering proposals to be printed", :js do + create(:proposal, title: 'Best proposal').update_column(:confidence_score, 10) + create(:proposal, title: 'Worst proposal').update_column(:confidence_score, 2) + create(:proposal, title: 'Medium proposal').update_column(:confidence_score, 5) + + user = create(:user, :level_two) + login_managed_user(user) + + visit print_management_proposals_path + + select 'most supported', from: 'order-selector' + + expect(page).to have_selector('.js-order-selector[data-order="confidence_score"]') + + within '#proposals' do + expect('Best proposal').to appear_before('Medium proposal') + expect('Medium proposal').to appear_before('Worst proposal') + end + + expect(current_url).to include('order=confidence_score') + expect(current_url).to include('page=1') + end + end + +end \ No newline at end of file diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index be03c1d2d..f1e47f5c3 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -28,6 +28,17 @@ module CommonActions click_button 'Log in' end + def login_as_manager(manager) + visit management_sign_in_path(login: manager.username, clave_usuario: manager.password) + end + + def login_managed_user(user) + #### + # CHANGE ME + # Should identify the user being managed + #### + end + def confirm_email expect(page).to have_content "A message with a confirmation link has been sent to your email address."