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 @@
+
+
+
+
\ 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."