diff --git a/app/assets/javascripts/tags.js.coffee b/app/assets/javascripts/tags.js.coffee index 12c4c3115..adbcad3e8 100644 --- a/app/assets/javascripts/tags.js.coffee +++ b/app/assets/javascripts/tags.js.coffee @@ -1,7 +1,7 @@ App.Tags = initialize: -> - $tag_input = $('input#debate_tag_list') + $tag_input = $('input.js-tag-list') $('body .js-add-tag-link').each -> $this = $(this) diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb index cf18ef51f..a527138e3 100644 --- a/app/controllers/proposals_controller.rb +++ b/app/controllers/proposals_controller.rb @@ -36,7 +36,7 @@ class ProposalsController < ApplicationController if @proposal.save_with_captcha ahoy.track :proposal_created, proposal_id: @proposal.id - redirect_to @proposal, notice: t('flash.actions.create.notice', resource_name: 'proposal') + redirect_to @proposal, notice: t('flash.actions.create.notice', resource_name: 'Proposal') else load_featured_tags render :new diff --git a/app/views/debates/_form.html.erb b/app/views/debates/_form.html.erb index 870f5081d..379ea60c2 100644 --- a/app/views/debates/_form.html.erb +++ b/app/views/debates/_form.html.erb @@ -20,7 +20,7 @@ <%= tag.name %> <% end %> - <%= f.text_field :tag_list, value: @debate.tag_list.to_s, label: false, placeholder: t("debates.form.tags_placeholder") %> + <%= f.text_field :tag_list, value: @debate.tag_list.to_s, label: false, placeholder: t("debates.form.tags_placeholder"), class: 'js-tag-list' %>
diff --git a/app/views/proposals/_form.html.erb b/app/views/proposals/_form.html.erb index 5607354fc..ce2714954 100644 --- a/app/views/proposals/_form.html.erb +++ b/app/views/proposals/_form.html.erb @@ -30,7 +30,7 @@ <%= tag.name %> <% end %> - <%= f.text_field :tag_list, value: @proposal.tag_list.to_s, label: false, placeholder: t("proposals.form.tags_placeholder") %> + <%= f.text_field :tag_list, value: @proposal.tag_list.to_s, label: false, placeholder: t("proposals.form.tags_placeholder"), class: 'js-tag-list' %>
diff --git a/spec/features/ckeditor_spec.rb b/spec/features/ckeditor_spec.rb new file mode 100644 index 000000000..7f5edc6e8 --- /dev/null +++ b/spec/features/ckeditor_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +feature 'CKEditor' do + + scenario 'is present before & after turbolinks update page', :js do + author = create(:user) + login_as(author) + + visit new_debate_path + + expect(page).to have_css "#cke_debate_description" + + click_link 'Debates' + click_link 'Start a debate' + + expect(page).to have_css "#cke_debate_description" + end + +end \ No newline at end of file diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index cc72a1b7d..79e6486c0 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -55,34 +55,20 @@ feature 'Debates' do login_as(author) visit new_debate_path - fill_in 'debate_title', with: 'Acabar con los desahucios' - fill_in 'debate_description', with: 'Esto es un tema muy importante porque...' + fill_in 'debate_title', with: 'End evictions' + fill_in 'debate_description', with: 'This is very important because...' fill_in 'debate_captcha', with: correct_captcha_text check 'debate_terms_of_service' click_button 'Start a debate' expect(page).to have_content 'Debate was successfully created.' - expect(page).to have_content 'Acabar con los desahucios' - expect(page).to have_content 'Esto es un tema muy importante porque...' + expect(page).to have_content 'End evictions' + expect(page).to have_content 'This is very important because...' expect(page).to have_content author.name expect(page).to have_content I18n.l(Debate.last.created_at.to_date) end - scenario 'CKEditor is present before & after turbolinks update page', :js do - author = create(:user) - login_as(author) - - visit new_debate_path - - expect(page).to have_css "#cke_debate_description" - - click_link 'Debates' - click_link 'Start a debate' - - expect(page).to have_css "#cke_debate_description" - end - scenario 'Captcha is required for debate creation' do login_as(create(:user)) diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 064299ba8..c2d5201cd 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -52,6 +52,282 @@ feature 'Proposals' do end end + scenario 'Create' 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_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 'This is very important because...' + expect(page).to have_content 'http://rescue.org/refugees' + expect(page).to have_content author.name + expect(page).to have_content I18n.l(Proposal.last.created_at.to_date) + end + + scenario 'Captcha is required for proposal creation' do + login_as(create(:user)) + + visit new_proposal_path + fill_in 'proposal_title', with: "Great title" + 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_external_url', with: 'http://rescue.org/refugees' + fill_in 'proposal_captcha', with: "wrongText!" + check 'proposal_terms_of_service' + + click_button "Start a proposal" + + expect(page).to_not have_content "Proposal was successfully created." + expect(page).to have_content "1 error" + + fill_in 'proposal_captcha', with: correct_captcha_text + click_button "Start a proposal" + + expect(page).to have_content "Proposal was successfully created." + end + + scenario 'Failed creation goes back to new showing featured tags' do + featured_tag = create(:tag, :featured) + tag = create(:tag) + login_as(create(:user)) + + visit new_proposal_path + fill_in 'proposal_title', with: "" + 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_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_not have_content "Proposal was successfully created." + expect(page).to have_content "error" + within(".tags") do + expect(page).to have_content featured_tag.name + expect(page).to_not have_content tag.name + end + end + + scenario 'Errors on create' do + author = create(:user) + login_as(author) + + visit new_proposal_path + click_button 'Start a proposal' + expect(page).to have_content error_message + end + + scenario 'JS injection is prevented but safe html is respected' do + author = create(:user) + login_as(author) + + visit new_proposal_path + fill_in 'proposal_title', with: 'Testing an attack' + fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?' + fill_in 'proposal_description', with: '

This is

' + 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.' + expect(page).to have_content 'Testing an attack' + expect(page.html).to include '

This is alert("an attack");

' + expect(page.html).to_not include '' + expect(page.html).to_not include '<p>This is' + end + + context 'Tagging proposals' do + let(:author) { create(:user) } + + background do + login_as(author) + end + + scenario 'using featured tags', :js do + ['Medio Ambiente', 'Ciencia'].each do |tag_name| + create(:tag, :featured, name: tag_name) + end + + visit new_proposal_path + + fill_in 'proposal_title', with: 'A test with enough characters' + 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 'proposal_external_url', with: 'http://rescue.org/refugees' + fill_in 'proposal_captcha', with: correct_captcha_text + check 'proposal_terms_of_service' + + ['Medio Ambiente', 'Ciencia'].each do |tag_name| + find('.js-add-tag-link', text: tag_name).click + end + + click_button 'Start a proposal' + + expect(page).to have_content 'Proposal was successfully created.' + ['Medio Ambiente', 'Ciencia'].each do |tag_name| + expect(page).to have_content tag_name + end + end + + scenario 'using dangerous strings' do + visit new_proposal_path + + fill_in 'proposal_title', with: 'A test of dangerous strings' + 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_external_url', with: 'http://rescue.org/refugees' + fill_in 'proposal_captcha', with: correct_captcha_text + check 'proposal_terms_of_service' + + fill_in 'proposal_tag_list', with: 'user_id=1, &a=3, ' + + click_button 'Start a proposal' + + expect(page).to have_content 'Proposal was successfully created.' + expect(page).to have_content 'user_id1' + expect(page).to have_content 'a3' + expect(page).to have_content 'scriptalert("hey");script' + expect(page.html).to_not include 'user_id=1, &a=3, ' + end + end + + scenario 'Update should not be posible if logged user is not the author' do + proposal = create(:proposal) + expect(proposal).to be_editable + login_as(create(:user)) + + visit edit_proposal_path(proposal) + expect(current_path).to eq(root_path) + expect(page).to have_content 'not authorized' + end + + scenario 'Update should not be posible if proposal is not editable' do + proposal = create(:proposal) + Setting.find_by(key: "max_votes_for_proposal_edit").update(value: 10) + 11.times { create(:vote, votable: proposal) } + + expect(proposal).to_not be_editable + + login_as(proposal.author) + visit edit_proposal_path(proposal) + + expect(current_path).to eq(root_path) + expect(page).to have_content 'not authorized' + end + + scenario 'Update should be posible for the author of an editable proposal' do + proposal = create(:proposal) + login_as(proposal.author) + + visit edit_proposal_path(proposal) + expect(current_path).to eq(edit_proposal_path(proposal)) + + fill_in 'proposal_title', with: "End child poverty" + 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_external_url', with: 'http://rescue.org/refugees' + fill_in 'proposal_captcha', with: correct_captcha_text + + click_button "Save changes" + + expect(page).to have_content "Proposal was successfully updated." + expect(page).to have_content "End child poverty" + expect(page).to have_content "Let's do something to end child poverty" + end + + scenario 'Errors on update' do + proposal = create(:proposal) + login_as(proposal.author) + + visit edit_proposal_path(proposal) + fill_in 'proposal_title', with: "" + click_button "Save changes" + + expect(page).to have_content error_message + end + + scenario 'Captcha is required to update a proposal' do + proposal = create(:proposal) + login_as(proposal.author) + + visit edit_proposal_path(proposal) + expect(current_path).to eq(edit_proposal_path(proposal)) + + fill_in 'proposal_title', with: "New cool title" + fill_in 'proposal_captcha', with: "wrong!" + click_button "Save changes" + + expect(page).to_not have_content "Proposal was successfully updated." + expect(page).to have_content "error" + + fill_in 'proposal_captcha', with: correct_captcha_text + click_button "Save changes" + + expect(page).to have_content "Proposal was successfully updated." + end + + scenario 'Failed update goes back to edit showing featured tags' do + proposal = create(:proposal) + featured_tag = create(:tag, :featured) + tag = create(:tag) + login_as(proposal.author) + + visit edit_proposal_path(proposal) + expect(current_path).to eq(edit_proposal_path(proposal)) + + fill_in 'proposal_title', with: "" + fill_in 'proposal_captcha', with: correct_captcha_text + click_button "Save changes" + + expect(page).to_not have_content "Proposal was successfully updated." + expect(page).to have_content "error" + within(".tags") do + expect(page).to have_content featured_tag.name + expect(page).to_not have_content tag.name + end + end + + describe 'Limiting tags shown' do + scenario 'Index page shows up to 5 tags per proposal' do + tag_list = ["Hacienda", "Economía", "Medio Ambiente", "Corrupción", "Fiestas populares", "Prensa", "Huelgas"] + create :proposal, tag_list: tag_list + + visit proposals_path + + within('.proposal .tags') do + expect(page).to have_content '2+' + end + end + + scenario 'Index page shows 3 tags with no plus link' do + tag_list = ["Medio Ambiente", "Corrupción", "Fiestas populares"] + create :proposal, tag_list: tag_list + + visit proposals_path + + within('.proposal .tags') do + tag_list.each do |tag| + expect(page).to have_content tag + end + expect(page).not_to have_content '+' + end + end + end + feature 'Proposal index order filters' do scenario 'Default order is confidence_score', :js do @@ -164,4 +440,15 @@ feature 'Proposals' do expect(page).to_not have_content(proposal3.title) end end + + scenario 'Conflictive' do + good_proposal = create(:proposal) + conflictive_proposal = create(:proposal, :conflictive) + + visit proposal_path(conflictive_proposal) + expect(page).to have_content "This proposal has been flag as innapropiate for some users." + + visit proposal_path(good_proposal) + expect(page).to_not have_content "This proposal has been flag as innapropiate for some users." + end end diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb index 2de06ce92..ff0e861ca 100644 --- a/spec/support/common_actions.rb +++ b/spec/support/common_actions.rb @@ -134,4 +134,5 @@ module CommonActions expect(page).to have_content 'Correct code' end + end