require "rails_helper" describe "Valuation budget investments" do let(:budget) { create(:budget, :valuating) } let(:valuator) do create(:valuator, user: create(:user, username: "Rachel", email: "rachel@valuators.org")) end before do login_as(valuator.user) end context "Load" do before { budget.update(slug: "budget_slug") } scenario "finds investment using budget slug" do visit valuation_budget_budget_investments_path("budget_slug") expect(page).to have_content budget.name end end describe "Index" do scenario "Index shows budget investments assigned to current valuator" do investment1 = create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator]) investment2 = create(:budget_investment, :visible_to_valuators, budget: budget) visit valuation_budget_budget_investments_path(budget) expect(page).to have_content(investment1.title) expect(page).not_to have_content(investment2.title) end scenario "Index shows no budget investment to admins no valuators" do investment1 = create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator]) investment2 = create(:budget_investment, :visible_to_valuators, budget: budget) logout login_as create(:administrator).user visit valuation_budget_budget_investments_path(budget) expect(page).not_to have_content(investment1.title) expect(page).not_to have_content(investment2.title) end scenario "Index orders budget investments by votes" do investment10 = create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator], cached_votes_up: 10) investment100 = create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator], cached_votes_up: 100) investment1 = create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator], cached_votes_up: 1) visit valuation_budget_budget_investments_path(budget) expect(investment100.title).to appear_before(investment10.title) expect(investment10.title).to appear_before(investment1.title) end scenario "Index displays investments paginated" do per_page = 3 allow(Budget::Investment).to receive(:default_per_page).and_return(per_page) (per_page + 2).times do create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator]) end visit valuation_budget_budget_investments_path(budget) expect(page).to have_css(".budget_investment", count: per_page) within("ul.pagination") do expect(page).to have_content("1") expect(page).to have_content("2") expect(page).not_to have_content("3") click_link "Next", exact: false end expect(page).to have_css(".budget_investment", count: 2) end scenario "Index filtering by heading" do group = create(:budget_group, budget: budget) valuating_heading = create(:budget_heading, name: "Only Valuating", group: group) valuating_finished_heading = create(:budget_heading, name: "Valuating&Finished", group: group) finished_heading = create(:budget_heading, name: "Only Finished", group: group) create(:budget_investment, :visible_to_valuators, title: "Valuating Investment ONE", heading: valuating_heading, budget: budget, valuators: [valuator]) create(:budget_investment, :visible_to_valuators, title: "Valuating Investment TWO", heading: valuating_finished_heading, budget: budget, valuators: [valuator]) create(:budget_investment, :visible_to_valuators, :finished, title: "Finished ONE", heading: valuating_finished_heading, budget: budget, valuators: [valuator]) create(:budget_investment, :visible_to_valuators, :finished, title: "Finished TWO", heading: finished_heading, budget: budget, valuators: [valuator]) visit valuation_budget_budget_investments_path(budget) expect(page).to have_link("Valuating Investment ONE") expect(page).to have_link("Valuating Investment TWO") expect(page).not_to have_link("Finished ONE") expect(page).not_to have_link("Finished TWO") expect(page).to have_link("All headings (4)") expect(page).to have_link("Only Valuating (1)") expect(page).to have_link("Valuating&Finished (2)") expect(page).to have_link("Only Finished (1)") click_link "Only Valuating (1)", exact: false expect(page).to have_link("Valuating Investment ONE") expect(page).not_to have_link("Valuating Investment TWO") expect(page).not_to have_link("Finished ONE") expect(page).not_to have_link("Finished TWO") click_link "Valuation finished" expect(page).not_to have_link("Valuating Investment ONE") expect(page).not_to have_link("Valuating Investment TWO") expect(page).not_to have_link("Finished ONE") expect(page).not_to have_link("Finished TWO") click_link "Valuating&Finished (2)", exact: false expect(page).not_to have_link("Valuating Investment ONE") expect(page).to have_link("Valuating Investment TWO") expect(page).not_to have_link("Finished ONE") expect(page).not_to have_link("Finished TWO") click_link "Valuation finished" expect(page).not_to have_link("Valuating Investment ONE") expect(page).not_to have_link("Valuating Investment TWO") expect(page).to have_link("Finished ONE") expect(page).not_to have_link("Finished TWO") click_link "Only Finished (1)", exact: false expect(page).not_to have_link("Valuating Investment ONE") expect(page).not_to have_link("Valuating Investment TWO") expect(page).not_to have_link("Finished ONE") expect(page).not_to have_link("Finished TWO") click_link "Valuation finished" expect(page).not_to have_link("Valuating Investment ONE") expect(page).not_to have_link("Valuating Investment TWO") expect(page).not_to have_link("Finished ONE") expect(page).to have_link("Finished TWO") end scenario "Current filter is properly highlighted" do filters_links = { "valuating" => "Under valuation", "valuation_finished" => "Valuation finished" } visit valuation_budget_budget_investments_path(budget) expect(page).not_to have_link(filters_links.values.first) filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } filters_links.each_pair do |current_filter, link| visit valuation_budget_budget_investments_path(budget, filter: current_filter) expect(page).not_to have_link(link) (filters_links.keys - [current_filter]).each do |filter| expect(page).to have_link(filters_links[filter]) end end end scenario "Index filtering by valuation status" do create(:budget_investment, :visible_to_valuators, budget: budget, valuators: [valuator], title: "Ongoing valuation") create(:budget_investment, :visible_to_valuators, :finished, budget: budget, valuators: [valuator], title: "Old idea") visit valuation_budget_budget_investments_path(budget) expect(page).to have_content("Ongoing valuation") expect(page).not_to have_content("Old idea") visit valuation_budget_budget_investments_path(budget, filter: "valuating") expect(page).to have_content("Ongoing valuation") expect(page).not_to have_content("Old idea") visit valuation_budget_budget_investments_path(budget, filter: "valuation_finished") expect(page).not_to have_content("Ongoing valuation") expect(page).to have_content("Old idea") end end describe "Show" do let(:administrator) do create(:administrator, user: create(:user, username: "Ana", email: "ana@admins.org")) end let(:second_valuator) do create(:valuator, user: create(:user, username: "Rick", email: "rick@valuators.org")) end let(:investment) do create(:budget_investment, :unfeasible, budget: budget, price: 1234, unfeasibility_explanation: "It is impossible", administrator: administrator, valuators: [valuator, second_valuator]) end scenario "visible for assigned valuators" do investment.update!(visible_to_valuators: true) visit valuation_budget_budget_investments_path(budget) click_link investment.title expect(page).to have_content("Investment preview") expect(page).to have_content(investment.title) expect(page).to have_content(investment.description) expect(page).to have_content(investment.author.name) expect(page).to have_content(investment.heading.name) expect(page).to have_content("1234") expect(page).to have_content("Unfeasible") expect(page).to have_content("It is impossible") expect(page).to have_content("Ana (ana@admins.org)") within("#assigned_valuators") do expect(page).to have_content("Rachel (rachel@valuators.org)") expect(page).to have_content("Rick (rick@valuators.org)") end end scenario "visible for admins" do logout login_as create(:administrator).user visit valuation_budget_budget_investment_path(budget, investment) expect(page).to have_content("Investment preview") expect(page).to have_content(investment.title) expect(page).to have_content(investment.description) expect(page).to have_content(investment.author.name) expect(page).to have_content(investment.heading.name) expect(page).to have_content("1234") expect(page).to have_content("Unfeasible") expect(page).to have_content("It is impossible") expect(page).to have_content("Ana (ana@admins.org)") within("#assigned_valuators") do expect(page).to have_content("Rachel (rachel@valuators.org)") expect(page).to have_content("Rick (rick@valuators.org)") end end end describe "Valuate" do let(:admin) { create(:administrator) } let(:investment) do create(:budget_investment, budget: budget, price: nil, administrator: admin, valuators: [valuator]) end scenario "Dossier empty by default" do investment.update!(visible_to_valuators: true) visit valuation_budget_budget_investments_path(budget) click_link investment.title within("#price") { expect(page).to have_content("Undefined") } within("#price_first_year") { expect(page).to have_content("Undefined") } within("#duration") { expect(page).to have_content("Undefined") } within("#feasibility") { expect(page).to have_content("Undecided") } expect(page).not_to have_content("Valuation finished") end scenario "Edit dossier" do investment.update!(visible_to_valuators: true) visit valuation_budget_budget_investments_path(budget) within("#budget_investment_#{investment.id}") do click_link "Edit dossier" end fill_in "budget_investment_price", with: "12345" fill_in "budget_investment_price_first_year", with: "9876" fill_in "budget_investment_price_explanation", with: "Very cheap idea" choose "budget_investment_feasibility_feasible" fill_in "budget_investment_duration", with: "19 months" click_button "Save changes" expect(page).to have_content "Dossier updated" visit valuation_budget_budget_investments_path(budget) click_link investment.title within("#price") { expect(page).to have_content("12345") } within("#price_first_year") { expect(page).to have_content("9876") } expect(page).to have_content("Very cheap idea") within("#duration") { expect(page).to have_content("19 months") } within("#feasibility") { expect(page).to have_content("Feasible") } expect(page).not_to have_content("Valuation finished") end scenario "Feasibility can be marked as pending" do visit valuation_budget_budget_investment_path(budget, investment) click_link "Edit dossier" expect(find("#budget_investment_feasibility_undecided")).to be_checked choose "budget_investment_feasibility_feasible" click_button "Save changes" expect(page).to have_content "Dossier updated" visit edit_valuation_budget_budget_investment_path(budget, investment) expect(find("#budget_investment_feasibility_undecided")).not_to be_checked expect(find("#budget_investment_feasibility_feasible")).to be_checked choose "budget_investment_feasibility_undecided" click_button "Save changes" expect(page).to have_content "Dossier updated" visit edit_valuation_budget_budget_investment_path(budget, investment) expect(find("#budget_investment_feasibility_undecided")).to be_checked end scenario "Feasibility selection makes proper fields visible" do feasible_fields = ["Price (€)", "Cost during the first year (€)", "Price explanation", "Time scope"] unfeasible_fields = ["Feasibility explanation"] any_feasibility_fields = ["Valuation finished"] undecided_fields = feasible_fields + unfeasible_fields + any_feasibility_fields visit edit_valuation_budget_budget_investment_path(budget, investment) expect(find("#budget_investment_feasibility_undecided")).to be_checked undecided_fields.each do |field| expect(page).to have_content(field) end choose "budget_investment_feasibility_feasible" unfeasible_fields.each do |field| expect(page).not_to have_content(field) end (feasible_fields + any_feasibility_fields).each do |field| expect(page).to have_content(field) end choose "budget_investment_feasibility_unfeasible" feasible_fields.each do |field| expect(page).not_to have_content(field) end (unfeasible_fields + any_feasibility_fields).each do |field| expect(page).to have_content(field) end click_button "Save changes" expect(page).to have_content "Dossier updated" visit edit_valuation_budget_budget_investment_path(budget, investment) expect(find("#budget_investment_feasibility_unfeasible")).to be_checked feasible_fields.each do |field| expect(page).not_to have_content(field) end (unfeasible_fields + any_feasibility_fields).each do |field| expect(page).to have_content(field) end choose "budget_investment_feasibility_undecided" undecided_fields.each do |field| expect(page).to have_content(field) end end scenario "Dossier hide price on hide money budgets" do budget = create(:budget, :valuating, :hide_money) investment = create(:budget_investment, budget: budget, administrator: admin, valuators: [valuator]) investment.update!(visible_to_valuators: true) visit valuation_budget_budget_investments_path(budget) within("#budget_investment_#{investment.id}") do click_link "Edit dossier" end expect(page).not_to have_content "Price (€)" expect(page).not_to have_content "Cost during the first year (€)" expect(page).not_to have_content "Price explanation" choose "budget_investment_feasibility_feasible" fill_in "budget_investment_duration", with: "12 months" click_button "Save changes" expect(page).to have_content "Dossier updated" visit valuation_budget_budget_investments_path(budget) click_link investment.title within("#duration") { expect(page).to have_content("12 months") } within("#feasibility") { expect(page).to have_content("Feasible") } expect(page).not_to have_css "#price" expect(page).not_to have_css "#price_first_year" end scenario "Finish valuation" do investment.update!(visible_to_valuators: true) visit valuation_budget_budget_investment_path(budget, investment) click_link "Edit dossier" accept_confirm { check "Valuation finished" } click_button "Save changes" expect(page).to have_content "Dossier updated" visit valuation_budget_budget_investments_path(budget) expect(page).not_to have_content investment.title click_link "Valuation finished" expect(page).to have_content investment.title click_link investment.title expect(page).to have_content "Investment preview" expect(page).to have_content "Valuation finished" end context "Reopen valuation" do before do investment.update( valuation_finished: true, feasibility: "feasible", unfeasibility_explanation: "Explanation is explanatory", price: 999, price_first_year: 666, price_explanation: "Democracy is not cheap", duration: "1 light year" ) end scenario "Admins can reopen & modify finished valuation" do logout login_as(admin.user) visit edit_valuation_budget_budget_investment_path(budget, investment) within_fieldset "Feasibility" do expect(page).to have_field "Undefined", type: :radio expect(page).to have_field "Feasible", type: :radio choose "Unfeasible" end expect(page).to have_field "Feasibility explanation", type: :textarea expect(page).to have_field "Valuation finished", type: :checkbox expect(page).to have_button "Save changes" end scenario "Valuators that are not admins cannot reopen or modify a finished valuation" do visit edit_valuation_budget_budget_investment_path(budget, investment) expect(page).not_to have_css "input[id='budget_investment_feasibility_undecided']" expect(page).not_to have_css "textarea[id='budget_investment_unfeasibility_explanation']" expect(page).not_to have_css "input[name='budget_investment[valuation_finished]']" expect(page).to have_content("Valuation finished") expect(page).to have_content("Feasibility: Feasible") expect(page).to have_content("Feasibility explanation: Explanation is explanatory") expect(page).to have_content("Price (€): 999") expect(page).to have_content("Cost during the first year: 666") expect(page).to have_content("Price explanation: Democracy is not cheap") expect(page).to have_content("Time scope: 1 light year") expect(page).not_to have_button("Save changes") end end scenario "Validates price formats on the server side", :no_js do investment.update!(visible_to_valuators: true) visit edit_valuation_budget_budget_investment_path(budget, investment) fill_in "Price (€)", with: "12345,98" fill_in "Cost during the first year (€) (optional, data not public)", with: "9876.6" click_button "Save changes" expect(page).to have_content("2 errors") expect(page).to have_content("Only integer numbers", count: 2) end scenario "not visible to valuators when budget is not valuating" do budget.update!(phase: "publishing_prices") investment = create(:budget_investment, budget: budget, valuators: [valuator]) login_as(valuator.user) visit edit_valuation_budget_budget_investment_path(budget, investment) expect(page).to have_content("Investments can only be valuated when Budget is in valuating phase") end scenario "restric access to the budget given by params when is not in valuating phase" do budget.update!(phase: "publishing_prices") create(:budget, :valuating) investment = create(:budget_investment, budget: budget, valuators: [valuator]) login_as(valuator.user) visit edit_valuation_budget_budget_investment_path(budget, investment) expect(page).to have_content("Investments can only be valuated when Budget is in valuating phase") end scenario "visible to admins regardless of not being in valuating phase" do budget.update!(phase: "publishing_prices") user = create(:user) admin = create(:administrator, user: user) valuator = create(:valuator, user: user) investment = create(:budget_investment, budget: budget, valuators: [valuator]) login_as(admin.user) visit valuation_budget_budget_investment_path(budget, investment) click_link "Edit dossier" expect(page).to have_content investment.title end end end