Merge pull request #590 from AyuntamientoMadrid/management-proposals

Management proposals
This commit is contained in:
Enrique García
2015-10-09 17:52:49 +02:00
23 changed files with 319 additions and 8 deletions

View File

@@ -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

View File

@@ -0,0 +1,10 @@
<%= form_for(Proposal.new, url: url, as: :proposal, method: :get) do |f| %>
<div class="row">
<div class="small-12 medium-6 column">
<%= text_field_tag :search, "", placeholder: t("admin.shared.proposal_search.placeholder") %>
</div>
<div class="form-inline small-12 medium-6 column">
<%= f.submit t("admin.shared.proposal_search.button"), class: "button radius success" %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1 @@
<%= render partial: 'proposals/proposal', locals: {proposal: proposal} %>

View File

@@ -0,0 +1,2 @@
<%= render 'proposals/votes',
{ proposal: proposal, vote_url: vote_management_proposal_path(proposal, value: 'yes') } %>

View File

@@ -0,0 +1,22 @@
<section role="main">
<%= render 'admin/shared/proposal_search', url: management_proposals_path %>
<div class="wrap row">
<div id="proposals" class="proposals-list small-12 medium-9 column">
<div class="filters">
<div class="small-12 medium-7 left">
<% if @search_terms %>
<h2 class="margin-top">
<%= page_entries_info @proposals %>
<%= t("proposals.index.search_results", count: @proposals.size, search_term: @search_terms) %>
</h2>
<% end %>
</div>
<%= render @proposals %>
<%= paginate @proposals %>
</div>
</div>
</div>
</section>

View File

@@ -0,0 +1,7 @@
<div class="proposal-new row">
<div class="small-12 medium-9 column">
<%= render "proposals/form", form_url: management_proposals_url %>
</div>
</div>

View File

@@ -0,0 +1,35 @@
<section id="printme" role="main">
<a id="print_link" onclick="print();" class="button warning radius">
<%= t('management.proposals.print.print_button') %>
</a>
<div class="wrap row">
<div id="proposals" class="proposals-list small-12 medium-9 column">
<div class="filters">
<div class="small-12 medium-7 left">
<div class="small-12 inline-block">
<h2 class="inline-block">
<%= t("proposals.index.select_order_long") %>
</h2>
<%= render 'shared/order_selector', i18n_namespace: "proposals.index" %>
</div>
</div>
</div>
<%= render @proposals %>
<%= paginate @proposals %>
</div>
</div>
</section>
<script type="text/javascript">
function print(){
var object=document.getElementById('printme');
var browser=window.open('','_blank');
browser.document.write(object.innerHTML);
browser.document.close();
browser.print();
browser.close();
}
</script>

View File

@@ -0,0 +1 @@
<%= render template: 'proposals/vote' %>

View File

@@ -1,4 +1,4 @@
<%= form_for(@proposal) do |f| %>
<%= form_for(@proposal, url: form_url) do |f| %>
<%= render 'shared/errors', resource: @proposal %>
<div class="row">

View File

@@ -47,7 +47,8 @@
</div>
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column text-center">
<%= render 'proposals/votes', proposal: proposal %>
<%= render 'votes',
{ proposal: proposal, vote_url: vote_proposal_path(proposal, value: 'yes') } %>
</div>
</div>

View File

@@ -22,7 +22,7 @@
<%= t("proposals.proposal.already_supported") %>
</div>
<% 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") %>

View File

@@ -12,6 +12,6 @@
<h1><%= t("proposals.edit.editing") %></h1>
<%= render "form" %>
<%= render "form", form_url: proposal_url(@proposal) %>
</div>
</div>

View File

@@ -44,7 +44,7 @@
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %>
</div>
<%= render @proposals %>
<%= render partial: 'proposals/proposal', collection: @proposals %>
<%= paginate @proposals %>
</div>
</div>

View File

@@ -11,7 +11,7 @@
<%= t("proposals.new.more_info")%>
<% end %>
</div>
<%= render "form" %>
<%= render "proposals/form", form_url: proposals_url %>
</div>
<div class="small-12 medium-3 column">

View File

@@ -97,7 +97,8 @@
<h3><%= t("votes.supports") %></h3>
<div class="text-center">
<div id="<%= dom_id(@proposal) %>_votes">
<%= render 'proposals/votes', proposal: @proposal %>
<%= render 'votes',
{ proposal: @proposal, vote_url: vote_proposal_path(@proposal, value: 'yes') } %>
</div>
</div>
<div class="sidebar-divider"></div>

View File

@@ -0,0 +1,2 @@
<%= render 'proposals/votes',
{ proposal: proposal, vote_url: vote_proposal_path(proposal, value: 'yes') } %>

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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:

View File

@@ -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

View File

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