require "rails_helper" describe "Proposals" do it_behaves_like "milestoneable", :proposal context "Concerns" do it_behaves_like "notifiable in-app", :proposal it_behaves_like "relationable", Proposal it_behaves_like "remotely_translatable", :proposal, "proposals_path", {} it_behaves_like "remotely_translatable", :proposal, "proposal_path", { id: "id" } it_behaves_like "flaggable", :proposal end context "Index" do before do Setting["feature.featured_proposals"] = true Setting["featured_proposals_number"] = 3 end let!(:featured_proposals) { create_featured_proposals } scenario "Lists featured and regular proposals" do proposals = [create(:proposal), create(:proposal), create(:proposal)] visit proposals_path expect(page).to have_css "#proposals .proposal-featured", count: 3 featured_proposals.each do |featured_proposal| within("#featured-proposals") do expect(page).to have_content featured_proposal.title expect(page).to have_link href: proposal_path(featured_proposal) end end expect(page).to have_css "#proposals .proposal", count: 3 proposals.each do |proposal| within("#proposals") do expect(page).to have_content proposal.title expect(page).to have_content proposal.summary expect(page).to have_link proposal.title, href: proposal_path(proposal) end end end scenario "Index view mode" do proposals = [create(:proposal), create(:proposal), create(:proposal)] visit proposals_path click_button "View mode" click_link "List" proposals.each do |proposal| within("#proposals") do expect(page).to have_link proposal.title expect(page).not_to have_content proposal.summary end end click_button "View mode" click_link "Cards" proposals.each do |proposal| within("#proposals") do expect(page).to have_link proposal.title expect(page).to have_content proposal.summary end end end scenario "Index view mode is not shown with selected filter" do visit proposals_path click_link "View selected proposals" expect(page).not_to have_css ".view-mode" expect(page).not_to have_button("View mode") end scenario "Pagination" do per_page = 3 allow(Proposal).to receive(:default_per_page).and_return(per_page) (per_page + 2).times { create(:proposal) } visit proposals_path expect(page).to have_css "#proposals .proposal", count: per_page within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_link("2", href: "/proposals?page=2") expect(page).not_to have_content("3") click_link "Next", exact: false end expect(page).to have_css "#proposals .proposal-featured", count: 3 expect(page).to have_css "#proposals .proposal", count: 2 end scenario "Index should show proposal descriptive image only when is defined" do proposal = create(:proposal) proposal_with_image = create(:proposal, :with_image) visit proposals_path within("#proposal_#{proposal.id}") do expect(page).not_to have_css("div.with-image") end within("#proposal_#{proposal_with_image.id}") do expect(page).to have_css("img[alt='#{proposal_with_image.image.title}']") end end end scenario "Show" do proposal = create(:proposal) visit proposal_path(proposal) expect(page).to have_content proposal.title expect(page).to have_content proposal.code expect(page).to have_content "Proposal description" expect(page).to have_content proposal.author.name expect(page).to have_content I18n.l(proposal.created_at.to_date) expect(page).to have_css avatar(proposal.author.name) expect(page.html).to include "#{proposal.title}" expect(page).not_to have_css ".js-flag-actions" expect(page).not_to have_css ".js-follow" end describe "Social share buttons" do context "On desktop browsers" do scenario "Shows links to share on facebook and twitter" do visit proposal_path(create(:proposal)) within(".social-share-button") do expect(page.all("a").count).to be(2) expect(page).to have_link "Share to Facebook" expect(page).to have_link "Share to Twitter" end end end context "On small devices", :small_window do scenario "Shows links to share on telegram and whatsapp too" do visit proposal_path(create(:proposal)) within(".social-share-button") do expect(page.all("a").count).to be(4) expect(page).to have_link "Share to Facebook" expect(page).to have_link "Share to Twitter" expect(page).to have_link "Share to Telegram" expect(page).to have_link "Share to WhatsApp" end end end end context "Show" do scenario "When path matches the friendly url" do proposal = create(:proposal) right_path = proposal_path(proposal) visit right_path expect(page).to have_current_path(right_path) end scenario "When path does not match the friendly url" do proposal = create(:proposal) right_path = proposal_path(proposal) old_path = "#{proposals_path}/#{proposal.id}-something-else" visit old_path expect(page).not_to have_current_path(old_path) expect(page).to have_current_path(right_path) end scenario "Can access the community" do Setting["feature.community"] = true proposal = create(:proposal) visit proposal_path(proposal) expect(page).to have_content "Access the community" end scenario "Can not access the community" do Setting["feature.community"] = false proposal = create(:proposal) visit proposal_path(proposal) expect(page).not_to have_content "Access the community" end scenario "Selected proposals does not show all information" do proposal = create(:proposal, :selected) login_as(create(:user)) visit proposal_path(proposal) expect(page).not_to have_content proposal.code expect(page).not_to have_content("Proposal code:") expect(page).not_to have_content("Related content") expect(page).not_to have_button("Add related content") within(".proposal-info") do expect(page).not_to have_link("No comments", href: "#comments") end end scenario "After using the browser's back button, social buttons will have one screen reader" do Setting["org_name"] = "CONSUL" proposal = create(:proposal) visit proposal_path(proposal) click_link "CONSUL" expect(page).to have_content "Most active proposals" go_back expect(page).to have_css "span.show-for-sr", text: "twitter", count: 1 end end describe "Sticky support button on medium and up screens" do scenario "is shown anchored to top" do proposal = create(:proposal) visit proposals_path click_link proposal.title within("#proposal_sticky") do expect(find(".is-anchored")).to match_style(top: "0px") end end end describe "Show sticky support button on small screens", :small_window do scenario "On a first visit" do proposal = create(:proposal) visit proposal_path(proposal) within("#proposal_sticky") do expect(page).to have_css(".is-stuck") expect(page).not_to have_css(".is-anchored") end end scenario "After visiting another page" do proposal = create(:proposal) visit proposal_path(proposal) click_link "Go back" click_link proposal.title within("#proposal_sticky") do expect(page).to have_css(".is-stuck") expect(page).not_to have_css(".is-anchored") end end scenario "After using the browser's back button" do proposal = create(:proposal) visit proposal_path(proposal) click_link "Go back" expect(page).to have_link proposal.title go_back within("#proposal_sticky") do expect(page).to have_css(".is-stuck") expect(page).not_to have_css(".is-anchored") end end scenario "After using the browser's forward button" do proposal = create(:proposal) visit proposals_path click_link proposal.title expect(page).not_to have_link proposal.title go_back expect(page).to have_link proposal.title go_forward within("#proposal_sticky") do expect(page).to have_css(".is-stuck") expect(page).not_to have_css(".is-anchored") end end end context "Embedded video" do scenario "Show YouTube video" do proposal = create(:proposal, video_url: "http://www.youtube.com/watch?v=a7UFm6ErMPU") visit proposal_path(proposal) expect(page).to have_css "div[id='js-embedded-video']" expect(page.html).to include "https://www.youtube.com/embed/a7UFm6ErMPU" end scenario "Show Vimeo video" do proposal = create(:proposal, video_url: "https://vimeo.com/7232823") visit proposal_path(proposal) expect(page).to have_css "div[id='js-embedded-video']" expect(page.html).to include "https://player.vimeo.com/video/7232823" end scenario "Dont show video" do proposal = create(:proposal, video_url: nil) visit proposal_path(proposal) expect(page).not_to have_css "div[id='js-embedded-video']" end end scenario "Social Media Cards" do proposal = create(:proposal) visit proposal_path(proposal) expect(page).to have_css "meta[name='twitter:title'][content='#{proposal.title}']", visible: :hidden expect(page).to have_css "meta[property='og:title'][content='#{proposal.title}']", visible: :hidden end scenario "Create and publish", :with_frozen_time do author = create(:user) login_as(author) visit new_proposal_path fill_in_new_proposal_title with: "Help refugees" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in_ckeditor "Proposal text", with: "This is very important because..." fill_in "External video URL", with: "https://www.youtube.com/watch?v=yPQfcG-eimk" fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" fill_in "Tags", with: "Refugees, Solidarity" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." expect(page).to have_content "Help refugees" expect(page).not_to have_content "You can also see more information about improving your campaign" click_link "No, I want to publish the proposal" expect(page).to have_content "Improve your campaign and get more support" click_link "Not now, go to my proposal" expect(page).to have_content "Help 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 "https://www.youtube.com/watch?v=yPQfcG-eimk" expect(page).to have_content author.name expect(page).to have_content "Refugees" expect(page).to have_content "Solidarity" expect(page).to have_content I18n.l(Date.current) end scenario "Create with invisible_captcha honeypot field", :no_js do author = create(:user) login_as(author) visit new_proposal_path fill_in "Proposal title", with: "I am a bot" fill_in "If you are human, ignore this field", with: "This is the honeypot field" fill_in "Proposal summary", with: "This is the summary" fill_in "Proposal text", with: "This is the description" fill_in "Full name of the person submitting the proposal", with: "Some other robot" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page.status_code).to eq(200) expect(page.html).to be_empty expect(page).to have_current_path(proposals_path) end scenario "Create proposal too fast" do allow(InvisibleCaptcha).to receive(:timestamp_threshold).and_return(Float::INFINITY) author = create(:user) login_as(author) visit new_proposal_path fill_in_new_proposal_title with: "I am a bot" fill_in "Proposal summary", with: "This is the summary" fill_in_ckeditor "Proposal text", with: "This is the description" fill_in "Full name of the person submitting the proposal", with: "Some other robot" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Sorry, that was too quick! Please resubmit" expect(page).to have_current_path(new_proposal_path) end scenario "Responsible name is stored for anonymous users" do author = create(:user) login_as(author) visit new_proposal_path fill_in_new_proposal_title with: "Help refugees" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in_ckeditor "Proposal text", with: "This is very important because..." fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" click_link "Dashboard" click_link "Edit my proposal" click_link "Edit proposal" expect(page).to have_field "Full name of the person submitting the proposal", with: "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).not_to have_field "Full name of the person submitting the proposal" fill_in_new_proposal_title with: "Help refugees" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in_ckeditor "Proposal text", with: "This is very important because..." check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" expect(Proposal.last.responsible_name).to eq(author.document_number) end scenario "Errors on create" do author = create(:user) login_as(author) visit new_proposal_path click_button "Create proposal" expect(page).to have_content error_message end scenario "JS injection is prevented but safe html is respected", :no_js do author = create(:user) login_as(author) visit new_proposal_path fill_in "Proposal title", with: "Testing an attack" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in "Proposal text", with: "

This is

" fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" expect(page).to have_content "Testing an attack" expect(page.html).to include "

This is alert('an attack');

" expect(page.html).not_to include "" expect(page.html).not_to include "<p>This is" end scenario "Autolinking is applied to description" do author = create(:user) login_as(author) visit new_proposal_path fill_in_new_proposal_title with: "Testing auto link" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in_ckeditor "Proposal text", with: "This is a link www.example.org" fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" expect(page).to have_content "Testing auto link" expect(page).to have_link("www.example.org", href: "http://www.example.org") end scenario "JS injection is prevented but autolinking is respected", :no_js do author = create(:user) js_injection_string = " " \ "click me " \ "http://example.org" login_as(author) visit new_proposal_path fill_in "Proposal title", with: "Testing auto link" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in "Proposal text", with: js_injection_string fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" expect(page).to have_content "Testing auto link" expect(page).to have_link("http://example.org", href: "http://example.org") expect(page).not_to have_link("click me") expect(page.html).not_to include "" click_link "Dashboard" within "#side_menu" do click_link "Edit my proposal" end click_link "Edit proposal" expect(page).to have_field "Proposal title", with: "Testing auto link" expect(page).not_to have_link("click me") expect(page.html).not_to include "" end context "Geozones" do scenario "When there are not gezones defined it does not show the geozone link" do visit proposal_path(create(:proposal)) expect(page).not_to have_css "#geozone" expect(page).not_to have_link "All city" end scenario "Default whole city" do create(:geozone) author = create(:user) login_as(author) visit new_proposal_path fill_in_proposal click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" within "#geozone" do expect(page).to have_content "All city" end end scenario "form shows the geozone selector when there are geozones defined" do create(:geozone) author = create(:user) login_as(author) visit new_proposal_path expect(page).to have_field("Scope of operation") end scenario "form do not show geozone selector when there are no geozones defined" do author = create(:user) login_as(author) visit new_proposal_path expect(page).not_to have_field("Scope of operation") end scenario "Specific geozone" do create(:geozone, name: "California") create(:geozone, name: "New York") login_as(create(:user)) visit new_proposal_path fill_in_new_proposal_title with: "Help refugees" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in_ckeditor "Proposal text", with: "This is very important because..." fill_in "External video URL", with: "https://www.youtube.com/watch?v=yPQfcG-eimk" fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" check "I agree to the Privacy Policy and the Terms and conditions of use" select("California", from: "proposal_geozone_id") click_button "Create proposal" expect(page).to have_content "Proposal created successfully." click_link "No, I want to publish the proposal" click_link "Not now, go to my proposal" within "#geozone" do expect(page).to have_content "California" end end end context "Withdrawn proposals" do scenario "Withdraw" do proposal = create(:proposal) login_as(proposal.author) visit user_path(proposal.author) within("#proposal_#{proposal.id}") do click_link "Dashboard" end within "#side_menu" do click_link "Edit my proposal" end click_link "Withdraw proposal" expect(page).to have_current_path(retire_form_proposal_path(proposal)) select "Duplicated", from: "proposal_retired_reason" fill_in "Explanation", with: "There are three other better proposals with the same subject" click_button "Withdraw proposal" expect(page).to have_content "The proposal has been withdrawn" visit proposal_path(proposal) expect(page).to have_content proposal.title expect(page).to have_content "Proposal withdrawn by the author" expect(page).to have_content "Duplicated" expect(page).to have_content "There are three other better proposals with the same subject" end scenario "Fields are mandatory" do proposal = create(:proposal) login_as(proposal.author) visit retire_form_proposal_path(proposal) click_button "Withdraw proposal" expect(page).not_to have_content "The proposal has been withdrawn" expect(page).to have_content "can't be blank", count: 2 end scenario "Index does not list withdrawn proposals by default" do Setting["feature.featured_proposals"] = true create_featured_proposals not_retired = create(:proposal) retired = create(:proposal, :retired) visit proposals_path expect(page).to have_css "#proposals .proposal", count: 1 within("#proposals") do expect(page).to have_content not_retired.title expect(page).not_to have_content retired.title end end scenario "Index has a link to the list of withdrawn proposals" do not_retired = create(:proposal) retired = create(:proposal, :retired) visit proposals_path expect(page).not_to have_content retired.title click_link "Proposals withdrawn by the author" expect(page).to have_content retired.title expect(page).not_to have_content not_retired.title end scenario "Withdrawn proposals index interface elements" do visit proposals_path(retired: "all") expect(page).not_to have_content "Advanced search" expect(page).not_to have_content "Categories" expect(page).not_to have_content "Districts" end scenario "Withdrawn proposals index has links to filter by retired_reason" do unfeasible = create(:proposal, :retired, retired_reason: "unfeasible") duplicated = create(:proposal, :retired, retired_reason: "duplicated") visit proposals_path(retired: "all") expect(page).to have_content unfeasible.title expect(page).to have_content duplicated.title expect(page).to have_link "Duplicated" expect(page).to have_link "Underway" expect(page).to have_link "Unfeasible" expect(page).to have_link "Done" expect(page).to have_link "Other" click_link "Unfeasible" expect(page).to have_content unfeasible.title expect(page).not_to have_content duplicated.title end context "Special interface translation behaviour" do before { Setting["feature.translation_interface"] = true } scenario "Cant manage translations" do proposal = create(:proposal) login_as(proposal.author) visit retire_form_proposal_path(proposal) expect(page).not_to have_css "#add_language" expect(page).not_to have_link "Remove language" end 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(page).not_to have_current_path(edit_proposal_path(proposal)) expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission" end scenario "Update should not be posible if proposal is not editable" do Setting["max_votes_for_proposal_edit"] = 3 proposal = create(:proposal, voters: Array.new(4) { create(:user) }) expect(proposal).not_to be_editable login_as(proposal.author) visit edit_proposal_path(proposal) expect(page).not_to have_current_path(edit_proposal_path(proposal)) expect(page).to have_current_path(root_path) expect(page).to have_content "You do not have permission" 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(page).to have_current_path(edit_proposal_path(proposal)) fill_in "Proposal title", with: "End child poverty" fill_in "Proposal summary", with: "Basically..." fill_in_ckeditor "Proposal text", with: "Let's do something to end child poverty" fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" click_button "Save changes" expect(page).to have_content "Proposal updated successfully." expect(page).to have_content "Basically..." 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 describe "Proposal index order filters" do scenario "Default order is hot_score" do best_proposal = create(:proposal, title: "Best proposal") best_proposal.update_column(:hot_score, 10) worst_proposal = create(:proposal, title: "Worst proposal") worst_proposal.update_column(:hot_score, 2) medium_proposal = create(:proposal, title: "Medium proposal") medium_proposal.update_column(:hot_score, 5) visit proposals_path expect(best_proposal.title).to appear_before(medium_proposal.title) expect(medium_proposal.title).to appear_before(worst_proposal.title) end scenario "Proposals are ordered by confidence_score" do best_proposal = create(:proposal, title: "Best proposal") best_proposal.update_column(:confidence_score, 10) worst_proposal = create(:proposal, title: "Worst proposal") worst_proposal.update_column(:confidence_score, 2) medium_proposal = create(:proposal, title: "Medium proposal") medium_proposal.update_column(:confidence_score, 5) visit proposals_path click_link "highest rated" expect(page).to have_css "a.is-active", text: "highest rated" within "#proposals" do expect(best_proposal.title).to appear_before(medium_proposal.title) expect(medium_proposal.title).to appear_before(worst_proposal.title) end expect(page).to have_current_path(/order=confidence_score/) expect(page).to have_current_path(/page=1/) end scenario "Proposals are ordered by newest" do best_proposal = create(:proposal, title: "Best proposal", created_at: Time.current) medium_proposal = create(:proposal, title: "Medium proposal", created_at: 1.hour.ago) worst_proposal = create(:proposal, title: "Worst proposal", created_at: 1.day.ago) visit proposals_path click_link "newest" expect(page).to have_css "a.is-active", text: "newest" within "#proposals" do expect(best_proposal.title).to appear_before(medium_proposal.title) expect(medium_proposal.title).to appear_before(worst_proposal.title) end expect(page).to have_current_path(/order=created_at/) expect(page).to have_current_path(/page=1/) end context "Recommendations" do let!(:best_proposal) { create(:proposal, title: "Best", cached_votes_up: 10, tag_list: "Sport") } let!(:medium_proposal) { create(:proposal, title: "Medium", cached_votes_up: 5, tag_list: "Sport") } let!(:worst_proposal) { create(:proposal, title: "Worst", cached_votes_up: 1, tag_list: "Sport") } scenario "can't be sorted if there's no logged user" do visit proposals_path expect(page).not_to have_css "a", text: "recommendations" end scenario "are shown on index header when account setting is enabled" do proposal = create(:proposal, tag_list: "Sport") user = create(:user, followables: [proposal]) login_as(user) visit proposals_path expect(page).to have_css(".recommendation", count: 3) expect(page).to have_link "Best" expect(page).to have_link "Medium" expect(page).to have_link "Worst" expect(page).to have_link "See more recommendations" end scenario "should display text when there are no results" do proposal = create(:proposal, tag_list: "Distinct_to_sport") user = create(:user, followables: [proposal]) login_as(user) visit proposals_path click_link "recommendations" expect(page).to have_content "There are not proposals related to your interests" end scenario "should display text when user has no related interests" do user = create(:user) login_as(user) visit proposals_path click_link "recommendations" expect(page).to have_content "Follow proposals so we can give you recommendations" end scenario "can be sorted when there's a logged user" do proposal = create(:proposal, tag_list: "Sport") user = create(:user, followables: [proposal]) login_as(user) visit proposals_path click_link "recommendations" expect(page).to have_css "a.is-active", text: "recommendations" within "#proposals-list" do expect(best_proposal.title).to appear_before(medium_proposal.title) expect(medium_proposal.title).to appear_before(worst_proposal.title) end expect(page).to have_current_path(/order=recommendations/) expect(page).to have_current_path(/page=1/) end scenario "are not shown if account setting is disabled" do proposal = create(:proposal, tag_list: "Sport") user = create(:user, recommended_proposals: false, followables: [proposal]) login_as(user) visit proposals_path expect(page).not_to have_css(".recommendation", count: 3) expect(page).not_to have_link("recommendations") end scenario "are automatically disabled when dismissed from index" do proposal = create(:proposal, tag_list: "Sport") user = create(:user, followables: [proposal]) login_as(user) visit proposals_path within("#recommendations") do expect(page).to have_content("Best") expect(page).to have_content("Worst") expect(page).to have_content("Medium") expect(page).to have_css(".recommendation", count: 3) accept_confirm { click_link "Hide recommendations" } end expect(page).not_to have_link("recommendations") expect(page).not_to have_css(".recommendation", count: 3) expect(page).to have_content("Recommendations for proposals are now disabled for this account") visit account_path expect(find("#account_recommended_proposals")).not_to be_checked end end end describe "Archived proposals" do scenario "show on proposals list" do archived_proposals = create_archived_proposals visit proposals_path click_link "Archived proposals" within("#proposals-list") do archived_proposals.each do |proposal| expect(page).to have_content(proposal.title) end end end scenario "do not show in other index tabs" do archived_proposal = create(:proposal, :archived) visit proposals_path within("#proposals-list") do expect(page).not_to have_content archived_proposal.title end orders = %w[hot_score confidence_score created_at relevance] orders.each do |order| visit proposals_path(order: order) within("#proposals-list") do expect(page).not_to have_content archived_proposal.title end end end scenario "do not show support buttons in index" do archived_proposals = create_archived_proposals visit proposals_path(order: "archival_date") within("#proposals-list") do archived_proposals.each do |proposal| within("#proposal_#{proposal.id}_votes") do expect(page).to have_content "This proposal has been archived and can't collect supports" end end end end scenario "do not show support buttons in show" do archived_proposal = create(:proposal, :archived) visit proposal_path(archived_proposal) expect(page).to have_content "This proposal has been archived and can't collect supports" end scenario "do not show in featured proposals section" do Setting["feature.featured_proposals"] = true featured_proposal = create(:proposal, :with_confidence_score, cached_votes_up: 100) archived_proposal = create(:proposal, :archived, :with_confidence_score, cached_votes_up: 10000) visit proposals_path within("#featured-proposals") do expect(page).to have_content(featured_proposal.title) expect(page).not_to have_content(archived_proposal.title) end within("#proposals-list") do expect(page).not_to have_content(featured_proposal.title) expect(page).not_to have_content(archived_proposal.title) end click_link "Archived proposals" within("#featured-proposals") do expect(page).to have_content(featured_proposal.title) expect(page).not_to have_content(archived_proposal.title) end within("#proposals-list") do expect(page).not_to have_content(featured_proposal.title) expect(page).to have_content(archived_proposal.title) end end scenario "Order by votes" do create(:proposal, :archived, title: "Least voted").update_column(:confidence_score, 10) create(:proposal, :archived, title: "Most voted").update_column(:confidence_score, 50) create(:proposal, :archived, title: "Some votes").update_column(:confidence_score, 25) visit proposals_path click_link "Archived proposals" within("#proposals-list") do expect(all(".proposal")[0].text).to match "Most voted" expect(all(".proposal")[1].text).to match "Some votes" expect(all(".proposal")[2].text).to match "Least voted" end end end context "Selected Proposals" do let!(:selected_proposal) { create(:proposal, :selected) } let!(:not_selected_proposal) { create(:proposal) } scenario "do not show in index by default" do visit proposals_path expect(page).to have_css "#proposals .proposal", count: 1 expect(page).to have_content not_selected_proposal.title expect(page).not_to have_content selected_proposal.title end scenario "show in selected proposals list" do visit proposals_path click_link "View selected proposals" expect(page).to have_css "#proposals .proposal", count: 1 expect(page).to have_content selected_proposal.title expect(page).not_to have_content not_selected_proposal.title end scenario "show a selected proposal message in show view" do visit proposal_path(selected_proposal) within("aside") { expect(page).not_to have_content "SUPPORTS" } within("aside") { expect(page).to have_content "Selected proposal" } end scenario "do not show featured proposal in selected proposals list" do Setting["feature.featured_proposals"] = true create_featured_proposals visit proposals_path expect(page).to have_css "#proposals .proposal-featured" expect(page).to have_css "#featured-proposals" click_link "View selected proposals" expect(page).not_to have_css "#proposals .proposal-featured" expect(page).not_to have_css "#featured-proposals" end scenario "do not show recommented proposal in selected proposals list" do user = create(:user) create(:proposal, tag_list: "Economy", followers: [user]) create(:proposal, title: "Recommended", tag_list: "Economy") login_as(user) visit proposals_path expect(page).to have_css(".recommendation", count: 1) expect(page).to have_link "Recommended" expect(page).to have_link "See more recommendations" click_link "View selected proposals" expect(page).not_to have_css ".recommendation" expect(page).not_to have_link "Recommended" expect(page).not_to have_link "See more recommendations" end scenario "do not show order links in selected proposals list" do visit proposals_path expect(page).to have_css "ul.submenu" expect(page).to have_link "most active" expect(page).to have_link "highest rated" expect(page).to have_link "newest" click_link "View selected proposals" expect(page).not_to have_css "ul.submenu" expect(page).not_to have_link "most active" expect(page).not_to have_link "highest rated" expect(page).not_to have_link "newest" end scenario "show archived proposals in selected proposals list" do archived_proposal = create(:proposal, :selected, :archived) visit proposals_path expect(page).not_to have_content archived_proposal.title click_link "View selected proposals" expect(page).to have_content archived_proposal.title end end context "Search" do context "Basic search" do scenario "Search by text" do proposal1 = create(:proposal, title: "Get Schwifty") proposal2 = create(:proposal, title: "Schwifty Hello") proposal3 = create(:proposal, title: "Do not show me") visit proposals_path within "#search_form" do fill_in "search", with: "Schwifty" click_button "Search" end within("#proposals") do expect(page).to have_css(".proposal", count: 2) expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) expect(page).not_to have_content(proposal3.title) end end scenario "Search by proposal code" do proposal1 = create(:proposal, title: "Get Schwifty") proposal2 = create(:proposal, title: "Schwifty Hello") visit proposals_path within "#search_form" do fill_in "search", with: proposal1.code click_button "Search" end within("#proposals") do expect(page).to have_css(".proposal", count: 1) expect(page).to have_content(proposal1.title) expect(page).not_to have_content(proposal2.title) end end scenario "Maintain search criteria" do visit proposals_path within "#search_form" do fill_in "search", with: "Schwifty" click_button "Search" end expect(page).to have_css "input[name='search'][value='Schwifty']" end end scenario "Order by relevance by default" do create(:proposal, title: "In summary", summary: "Title content too", cached_votes_up: 10) create(:proposal, title: "Title content", summary: "Summary", cached_votes_up: 1) create(:proposal, title: "Title here", summary: "Content here", cached_votes_up: 100) visit proposals_path fill_in "search", with: "Title content" click_button "Search" expect(page).to have_css "a.is-active", text: "relevance" within("#proposals") do expect(all(".proposal")[0].text).to match "Title content" expect(all(".proposal")[1].text).to match "Title here" expect(all(".proposal")[2].text).to match "In summary" end end scenario "Reorder results maintaing search" do create(:proposal, title: "Show you got", cached_votes_up: 10, created_at: 1.week.ago) create(:proposal, title: "Show what you got", cached_votes_up: 1, created_at: 1.month.ago) create(:proposal, title: "Show you got", cached_votes_up: 100, created_at: Time.current) create(:proposal, title: "Do not display", cached_votes_up: 1, created_at: 1.week.ago) visit proposals_path fill_in "search", with: "Show what you got" click_button "Search" expect(page).to have_content "Search results" click_link "newest" expect(page).to have_css "a.is-active", text: "newest" within("#proposals") do expect(all(".proposal")[0].text).to match "Show you got" expect(all(".proposal")[1].text).to match "Show you got" expect(all(".proposal")[2].text).to match "Show what you got" expect(page).not_to have_content "Do not display" end end scenario "Reorder by recommendations results maintaing search" do user = create(:user, recommended_proposals: true) create(:proposal, title: "Show you got", cached_votes_up: 10, tag_list: "Sport") create(:proposal, title: "Show what you got", cached_votes_up: 1, tag_list: "Sport") create(:proposal, title: "Do not display with same tag", cached_votes_up: 100, tag_list: "Sport") create(:proposal, title: "Do not display", cached_votes_up: 1) create(:proposal, tag_list: "Sport", followers: [user]) login_as(user) visit proposals_path fill_in "search", with: "Show you got" click_button "Search" click_link "recommendations" expect(page).to have_css "a.is-active", text: "recommendations" within("#proposals") do expect(all(".proposal")[0].text).to match "Show you got" expect(all(".proposal")[1].text).to match "Show what you got" expect(page).not_to have_content "Do not display with same tag" expect(page).not_to have_content "Do not display" end end scenario "After a search do not show featured proposals" do Setting["feature.featured_proposals"] = true create_featured_proposals create(:proposal, title: "Abcdefghi") visit proposals_path within "#search_form" do fill_in "search", with: "Abcdefghi" click_button "Search" end expect(page).not_to have_css "#proposals .proposal-featured" expect(page).not_to have_css "#featured-proposals" 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 flagged as inappropriate by several users." visit proposal_path(good_proposal) expect(page).not_to have_content "This proposal has been flagged as inappropriate by several users." end it_behaves_like "followable", "proposal", "proposal_path", { id: "id" } it_behaves_like "imageable", "proposal", "proposal_path", { id: "id" } it_behaves_like "nested imageable", "proposal", "new_proposal_path", {}, "imageable_fill_new_valid_proposal", "Create proposal", "Proposal created successfully" it_behaves_like "nested imageable", "proposal", "edit_proposal_path", { id: "id" }, nil, "Save changes", "Proposal updated successfully" it_behaves_like "documentable", "proposal", "proposal_path", { id: "id" } it_behaves_like "nested documentable", "user", "proposal", "new_proposal_path", {}, "documentable_fill_new_valid_proposal", "Create proposal", "Proposal created successfully" it_behaves_like "nested documentable", "user", "proposal", "edit_proposal_path", { id: "id" }, nil, "Save changes", "Proposal updated successfully" it_behaves_like "mappable", "proposal", "proposal", "new_proposal_path", "edit_proposal_path", "proposal_path" scenario "Erased author" do user = create(:user) proposal = create(:proposal, author: user) user.erase visit proposals_path expect(page).to have_content("User deleted") visit proposal_path(proposal) expect(page).to have_content("User deleted") end scenario "Erased author with featured proposals" do Setting["feature.featured_proposals"] = true user = create(:proposal).author user.erase create_featured_proposals visit proposals_path expect(page).to have_content("User deleted") end context "Filter" do context "By geozone" do let(:california) { Geozone.create(name: "California") } let(:new_york) { Geozone.create(name: "New York") } before do create(:proposal, geozone: california, title: "Bigger sequoias") create(:proposal, geozone: california, title: "Green beach") create(:proposal, geozone: new_york, title: "Sully monument") end scenario "From map", :no_js do visit proposals_path click_link "map" within("#html_map") do url = find("area[title='California']")[:href] visit url end within("#proposals") do expect(page).to have_css(".proposal", count: 2) expect(page).to have_content("Bigger sequoias") expect(page).to have_content("Green beach") expect(page).not_to have_content("Sully monument") end end scenario "From geozone list" do visit proposals_path click_link "map" within("#geozones") do click_link "California" end within("#proposals") do expect(page).to have_css(".proposal", count: 2) expect(page).to have_content("Bigger sequoias") expect(page).to have_content("Green beach") expect(page).not_to have_content("Sully monument") end end scenario "From proposal" do proposal = create(:proposal, geozone: california, title: "Surf college") visit proposal_path(proposal) within("#geozone") do click_link "California" end within("#proposals") do expect(page).to have_css(".proposal", count: 3) expect(page).to have_content("Surf college") expect(page).to have_content("Bigger sequoias") expect(page).to have_content("Green beach") expect(page).not_to have_content("Sully monument") end end end end context "Suggesting proposals" do scenario "Show up to 5 suggestions" do create(:proposal, title: "First proposal, has search term") create(:proposal, title: "Second title") create(:proposal, title: "Third proposal, has search term") create(:proposal, title: "Fourth proposal, has search term") create(:proposal, title: "Fifth proposal, has search term") create(:proposal, title: "Sixth proposal, has search term") create(:proposal, title: "Seventh proposal, has search term") login_as(create(:user)) visit new_proposal_path fill_in "Proposal title", with: "search" check "I agree to the Privacy Policy and the Terms and conditions of use" within("div.js-suggest") do expect(page).to have_content "You are seeing 5 of 6 proposals containing the term 'search'" end end scenario "No found suggestions" do create(:proposal, title: "First proposal").update_column(:confidence_score, 10) create(:proposal, title: "Second proposal").update_column(:confidence_score, 8) login_as(create(:user)) visit new_proposal_path fill_in "Proposal title", with: "debate" check "I agree to the Privacy Policy and the Terms and conditions of use" within("div.js-suggest") do expect(page).not_to have_content "You are seeing" end end describe "Don't show suggestions" do let(:user) { create(:user) } let(:proposal) { create(:proposal, title: "Proposal title, has search term", author: user) } before do login_as(user) visit edit_proposal_path(proposal) end scenario "for edit action" do fill_in "Proposal title", with: "search" expect(page).not_to have_content "There is a proposal with the term 'search'" end scenario "for update action" do fill_in "Proposal title", with: "" click_button "Save changes" fill_in "Proposal title", with: "search" expect(page).not_to have_content "There is a proposal with the term 'search'" end end end context "Summary" do scenario "Displays proposals grouped by category" do create(:tag, :category, name: "Culture") create(:tag, :category, name: "Social Services") 3.times { create(:proposal, tag_list: "Culture") } 3.times { create(:proposal, tag_list: "Social Services") } create(:proposal, tag_list: "Random") visit proposals_path click_link "The most supported proposals by category" within("#culture") do expect(page).to have_content("Culture") expect(page).to have_css(".proposal", count: 3) end within("#social-services") do expect(page).to have_content("Social Services") expect(page).to have_css(".proposal", count: 3) end end scenario "Displays proposals grouped by district" do california = create(:geozone, name: "California") new_york = create(:geozone, name: "New York") 3.times { create(:proposal, geozone: california) } 3.times { create(:proposal, geozone: new_york) } visit proposals_path click_link "The most supported proposals by category" within("#california") do expect(page).to have_content("California") expect(page).to have_css(".proposal", count: 3) end within("#new-york") do expect(page).to have_content("New York") expect(page).to have_css(".proposal", count: 3) end end scenario "Displays a maximum of 3 proposals per category" do create(:tag, :category, name: "culture") 4.times { create(:proposal, tag_list: "culture") } visit summary_proposals_path expect(page).to have_css(".proposal", count: 3) end scenario "Orders proposals by votes" do create(:tag, :category, name: "culture") best_proposal = create(:proposal, title: "Best", tag_list: "culture") best_proposal.update_column(:confidence_score, 10) worst_proposal = create(:proposal, title: "Worst", tag_list: "culture") worst_proposal.update_column(:confidence_score, 2) medium_proposal = create(:proposal, title: "Medium", tag_list: "culture") medium_proposal.update_column(:confidence_score, 5) visit summary_proposals_path expect(best_proposal.title).to appear_before(medium_proposal.title) expect(medium_proposal.title).to appear_before(worst_proposal.title) end scenario "Displays proposals from last week" do create(:tag, :category, name: "culture") proposal1 = create(:proposal, tag_list: "culture", created_at: 1.day.ago) proposal2 = create(:proposal, tag_list: "culture", created_at: 5.days.ago) proposal3 = create(:proposal, tag_list: "culture", created_at: 8.days.ago) visit summary_proposals_path within("#proposals") do expect(page).to have_css(".proposal", count: 2) expect(page).to have_content(proposal1.title) expect(page).to have_content(proposal2.title) expect(page).not_to have_content(proposal3.title) end end end end describe "Successful proposals" do scenario "Successful proposals do not show support buttons in index" do successful_proposals = create_successful_proposals visit proposals_path successful_proposals.each do |proposal| within("#proposal_#{proposal.id}_votes") do expect(page).not_to have_link "Support" expect(page).to have_content "100% / 100%" end end end scenario "Successful proposals do not show support buttons in show" do successful_proposals = create_successful_proposals successful_proposals.each do |proposal| visit proposal_path(proposal) within("#proposal_#{proposal.id}_votes") do expect(page).not_to have_link "Support" expect(page).to have_content "100% / 100%" end end end scenario "Successful proposals do not show create question button in index", :admin do successful_proposals = create_successful_proposals visit proposals_path successful_proposals.each do |proposal| within("#proposal_#{proposal.id}_votes") do expect(page).not_to have_link "Create question" end end end scenario "Successful proposals do not show create question button in show", :admin do successful_proposals = create_successful_proposals successful_proposals.each do |proposal| visit proposal_path(proposal) within("#proposal_#{proposal.id}_votes") do expect(page).not_to have_link "Create question" end end end context "Skip user verification" do before do Setting["feature.user.skip_verification"] = "true" end scenario "Create" do author = create(:user) login_as(author) visit proposals_path within("aside") do click_link "Create a proposal" end expect(page).to have_current_path(new_proposal_path) fill_in_new_proposal_title with: "Help refugees" fill_in "Proposal summary", with: "In summary what we want is..." fill_in_ckeditor "Proposal text", with: "This is very important because..." fill_in "External video URL", with: "https://www.youtube.com/watch?v=yPQfcG-eimk" fill_in "Tags", with: "Refugees, Solidarity" check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" expect(page).to have_content "Proposal created successfully." end end describe "SDG related list" do let(:user) { create(:user) } before do Setting["feature.sdg"] = true Setting["sdg.process.proposals"] = true end scenario "create proposal with sdg related list" do login_as(user) visit new_proposal_path fill_in_new_proposal_title with: "A title for a proposal related with SDG related content" fill_in "Proposal summary", with: "In summary, what we want is..." fill_in "Full name of the person submitting the proposal", with: "Isabel Garcia" click_sdg_goal(1) check "I agree to the Privacy Policy and the Terms and conditions of use" click_button "Create proposal" within(".sdg-goal-tag-list") { expect(page).to have_link "1. No Poverty" } end scenario "edit proposal with sdg related list" do proposal = create(:proposal, author: user) proposal.sdg_goals = [SDG::Goal[1], SDG::Goal[2]] login_as(user) visit edit_proposal_path(proposal) remove_sdg_goal_or_target_tag(1) click_button "Save changes" within(".sdg-goal-tag-list") do expect(page).not_to have_link "1. No Poverty" expect(page).to have_link "2. Zero Hunger" end end end end