adds responsible name to proposals

This commit is contained in:
rgarcia
2015-09-14 16:43:32 +02:00
parent 47ebc41c69
commit e9e339fa50
10 changed files with 128 additions and 7 deletions

View File

@@ -75,7 +75,7 @@ class ProposalsController < ApplicationController
private private
def proposal_params def proposal_params
params.require(:proposal).permit(:title, :question, :description, :external_url, :tag_list, :terms_of_service, :captcha, :captcha_key) params.require(:proposal).permit(:title, :question, :description, :external_url, :responsible_name, :tag_list, :terms_of_service, :captcha, :captcha_key)
end end
def load_featured_tags def load_featured_tags

View File

@@ -14,15 +14,18 @@ class Proposal < ActiveRecord::Base
validates :question, presence: true validates :question, presence: true
validates :description, presence: true validates :description, presence: true
validates :author, presence: true validates :author, presence: true
validates :responsible_name, presence: true
validate :validate_title_length validate :validate_title_length
validate :validate_question_length validate :validate_question_length
validate :validate_description_length validate :validate_description_length
validate :validate_responsible_length
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
before_validation :sanitize_description before_validation :sanitize_description
before_validation :sanitize_tag_list before_validation :sanitize_tag_list
before_validation :set_responsible_name
scope :for_render, -> { includes(:tags) } scope :for_render, -> { includes(:tags) }
scope :sort_by_hot_score , -> { order(hot_score: :desc) } scope :sort_by_hot_score , -> { order(hot_score: :desc) }
@@ -96,6 +99,10 @@ class Proposal < ActiveRecord::Base
6000 6000
end end
def self.responsible_name_max_length
60
end
def self.search(terms) def self.search(terms)
terms.present? ? where("title ILIKE ? OR description ILIKE ? OR question ILIKE ?", "%#{terms}%", "%#{terms}%", "%#{terms}%") : none terms.present? ? where("title ILIKE ? OR description ILIKE ? OR question ILIKE ?", "%#{terms}%", "%#{terms}%", "%#{terms}%") : none
end end
@@ -114,6 +121,11 @@ class Proposal < ActiveRecord::Base
self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list) self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list)
end end
def set_responsible_name
if author && author.level_two_or_three_verified?
self.responsible_name = author.document_number
end
end
private private
def validate_description_length def validate_description_length
@@ -140,4 +152,12 @@ class Proposal < ActiveRecord::Base
validator.validate(self) validator.validate(self)
end end
def validate_responsible_length
validator = ActiveModel::Validations::LengthValidator.new(
attributes: :title,
minimum: 6,
maximum: Proposal.responsible_name_max_length)
validator.validate(self)
end
end end

View File

@@ -33,6 +33,13 @@
<%= f.text_field :tag_list, value: @proposal.tag_list.to_s, label: false, placeholder: t("proposals.form.tags_placeholder"), class: 'js-tag-list' %> <%= f.text_field :tag_list, value: @proposal.tag_list.to_s, label: false, placeholder: t("proposals.form.tags_placeholder"), class: 'js-tag-list' %>
</div> </div>
<% if current_user.unverified? %>
<div class="small-12 column">
<%= f.label :responsible_name, t("proposals.form.proposal_responsible_name") %>
<%= f.text_field :responsible_name, placeholder: t("proposals.form.proposal_responsible_name"), label: false %>
</div>
<% end %>
<div class="small-12 column"> <div class="small-12 column">
<% if @proposal.new_record? %> <% if @proposal.new_record? %>
<%= f.label :terms_of_service do %> <%= f.label :terms_of_service do %>

View File

@@ -174,6 +174,7 @@ en:
proposal_question: Proposal question proposal_question: Proposal question
proposal_text: Initial text for proposal proposal_text: Initial text for proposal
proposal_external_url: Link to additional documentation proposal_external_url: Link to additional documentation
proposal_responsible_name: "First and last name of the person making this proposal"
tags_label: Topics tags_label: Topics
tags_instructions: > tags_instructions: >
Tag this proposal. You can choose among our proposals on the list or add any other topic you want. Tag this proposal. You can choose among our proposals on the list or add any other topic you want.

View File

@@ -176,6 +176,7 @@ es:
proposal_question: Pregunta de la propuesta proposal_question: Pregunta de la propuesta
proposal_text: Texto inicial de la propuesta proposal_text: Texto inicial de la propuesta
proposal_external_url: Enlace a documentación adicional proposal_external_url: Enlace a documentación adicional
proposal_responsible_name: "Nombre y apellidos de la persona que hace esta propuesta"
tags_label: Temas tags_label: Temas
tags_instructions: > tags_instructions: >
Etiqueta esta propuesta. Puedes elegir entre nuestras propuestas o introducir las que desees. Etiqueta esta propuesta. Puedes elegir entre nuestras propuestas o introducir las que desees.

View File

@@ -0,0 +1,5 @@
class AddResponsibleToProposals < ActiveRecord::Migration
def change
add_column :proposals, :responsible_name, :string, limit: 60
end
end

View File

@@ -11,10 +11,11 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20150912145218) do ActiveRecord::Schema.define(version: 20150914113251) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
enable_extension "unaccent"
create_table "addresses", force: :cascade do |t| create_table "addresses", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
@@ -165,7 +166,7 @@ ActiveRecord::Schema.define(version: 20150912145218) do
create_table "locks", force: :cascade do |t| create_table "locks", force: :cascade do |t|
t.integer "user_id" t.integer "user_id"
t.integer "tries", default: 0 t.integer "tries", default: 0
t.datetime "locked_until", default: '2015-09-11 17:24:30', null: false t.datetime "locked_until", default: '2015-09-10 13:46:11', null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
end end
@@ -204,6 +205,7 @@ ActiveRecord::Schema.define(version: 20150912145218) do
t.integer "confidence_score", default: 0 t.integer "confidence_score", default: 0
t.datetime "created_at", null: false t.datetime "created_at", null: false
t.datetime "updated_at", null: false t.datetime "updated_at", null: false
t.string "responsible_name", limit: 60
end end
create_table "settings", force: :cascade do |t| create_table "settings", force: :cascade do |t|

View File

@@ -7,6 +7,17 @@ FactoryGirl.define do
terms_of_service '1' terms_of_service '1'
confirmed_at { Time.now } confirmed_at { Time.now }
trait :level_two do
residence_verified_at Time.now
confirmed_phone "611111111"
document_number "12345678Z"
end
trait :level_three do
verified_at Time.now
document_number "12345678Z"
end
trait :hidden do trait :hidden do
hidden_at Time.now hidden_at Time.now
end end
@@ -106,6 +117,7 @@ FactoryGirl.define do
description 'Proposal description' description 'Proposal description'
question 'Proposal question' question 'Proposal question'
external_url 'http://external_documention.es' external_url 'http://external_documention.es'
responsible_name 'John Snow'
terms_of_service '1' terms_of_service '1'
association :author, factory: :user association :author, factory: :user

View File

@@ -61,6 +61,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: 'This is very important because...' fill_in 'proposal_description', with: 'This is very important because...'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -75,6 +76,45 @@ feature 'Proposals' do
expect(page).to have_content I18n.l(Proposal.last.created_at.to_date) expect(page).to have_content I18n.l(Proposal.last.created_at.to_date)
end end
scenario 'Responsible name is stored for anonymous users' do
author = create(:user)
login_as(author)
visit new_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_description', with: 'This is very important because...'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
check 'proposal_terms_of_service'
click_button 'Start a proposal'
expect(page).to have_content 'Proposal was successfully created.'
expect(Proposal.last.responsible_name).to eq('Isabel Garcia')
end
scenario 'Responsible name field is not shown for verified users' do
author = create(:user, :level_two)
login_as(author)
visit new_proposal_path
expect(page).to_not have_selector('#proposal_responsible_name')
fill_in 'proposal_title', with: 'Help refugees'
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: 'This is very important because...'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
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.'
end
scenario 'Captcha is required for proposal creation' do scenario 'Captcha is required for proposal creation' do
login_as(create(:user)) login_as(create(:user))
@@ -83,6 +123,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: 'Very important issue...' fill_in 'proposal_description', with: 'Very important issue...'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: "wrongText!" fill_in 'proposal_captcha', with: "wrongText!"
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -107,6 +148,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: 'Very important issue...' fill_in 'proposal_description', with: 'Very important issue...'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -138,6 +180,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: '<p>This is <script>alert("an attack");</script></p>' fill_in 'proposal_description', with: '<p>This is <script>alert("an attack");</script></p>'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -158,6 +201,7 @@ feature 'Proposals' do
fill_in 'proposal_title', with: 'Testing auto link' fill_in 'proposal_title', with: 'Testing auto link'
fill_in 'proposal_question', with: 'Should I stay or should I go?' fill_in 'proposal_question', with: 'Should I stay or should I go?'
fill_in 'proposal_description', with: '<p>This is a link www.example.org</p>' fill_in 'proposal_description', with: '<p>This is a link www.example.org</p>'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -176,6 +220,7 @@ feature 'Proposals' do
fill_in 'proposal_title', with: 'Testing auto link' fill_in 'proposal_title', with: 'Testing auto link'
fill_in 'proposal_question', with: 'Should I stay or should I go?' fill_in 'proposal_question', with: 'Should I stay or should I go?'
fill_in 'proposal_description', with: "<script>alert('hey')</script> <a href=\"javascript:alert('surprise!')\">click me<a/> http://example.org" fill_in 'proposal_description', with: "<script>alert('hey')</script> <a href=\"javascript:alert('surprise!')\">click me<a/> http://example.org"
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -212,6 +257,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in_ckeditor 'proposal_description', with: 'A description with enough characters' fill_in_ckeditor 'proposal_description', with: 'A description with enough characters'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -234,6 +280,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: 'A description suitable for this test' fill_in 'proposal_description', with: 'A description suitable for this test'
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
check 'proposal_terms_of_service' check 'proposal_terms_of_service'
@@ -284,6 +331,7 @@ feature 'Proposals' do
fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
fill_in 'proposal_description', with: "Let's do something to end child poverty" fill_in 'proposal_description', with: "Let's do something to end child poverty"
fill_in 'proposal_external_url', with: 'http://rescue.org/refugees' fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
fill_in 'proposal_captcha', with: correct_captcha_text fill_in 'proposal_captcha', with: correct_captcha_text
click_button "Save changes" click_button "Save changes"

View File

@@ -12,13 +12,13 @@ describe Proposal do
expect(proposal).to_not be_valid expect(proposal).to_not be_valid
end end
it "should not be valid without a question" do it "should not be valid without a title" do
proposal.question = nil proposal.title = nil
expect(proposal).to_not be_valid expect(proposal).to_not be_valid
end end
it "should not be valid without a title" do it "should not be valid without a question" do
proposal.title = nil proposal.question = nil
expect(proposal).to_not be_valid expect(proposal).to_not be_valid
end end
@@ -35,6 +35,31 @@ describe Proposal do
end end
end end
describe "#responsible" do
it "should be mandatory" do
proposal.responsible_name = nil
expect(proposal).to_not be_valid
end
it "should be the document_number if level two user" do
author = create(:user, :level_two, document_number: "12345678Z")
proposal.author = author
proposal.responsible_name = nil
expect(proposal).to be_valid
proposal.responsible_name = "12345678Z"
end
it "should be the document_number if level two user" do
author = create(:user, :level_three, document_number: "12345678Z")
proposal.author = author
proposal.responsible_name = nil
expect(proposal).to be_valid
proposal.responsible_name = "12345678Z"
end
end
it "should sanitize the tag list" do it "should sanitize the tag list" do
proposal.tag_list = "user_id=1" proposal.tag_list = "user_id=1"
proposal.valid? proposal.valid?