330 lines
10 KiB
Ruby
330 lines
10 KiB
Ruby
require "rails_helper"
|
|
|
|
describe "Admin budgets" do
|
|
|
|
before do
|
|
admin = create(:administrator)
|
|
login_as(admin.user)
|
|
end
|
|
|
|
it_behaves_like "edit_translatable",
|
|
"budget",
|
|
"edit_admin_budget_path",
|
|
%w[name]
|
|
|
|
context "Feature flag" do
|
|
|
|
before do
|
|
Setting["process.budgets"] = nil
|
|
end
|
|
|
|
scenario "Disabled with a feature flag" do
|
|
expect{ visit admin_budgets_path }.to raise_exception(FeatureFlags::FeatureDisabled)
|
|
end
|
|
|
|
end
|
|
|
|
context "Load" do
|
|
|
|
let!(:budget) { create(:budget, slug: "budget_slug") }
|
|
|
|
scenario "finds budget by slug" do
|
|
visit admin_budget_path("budget_slug")
|
|
expect(page).to have_content(budget.name)
|
|
end
|
|
|
|
scenario "raises an error if budget slug is not found" do
|
|
expect do
|
|
visit admin_budget_path("wrong_budget")
|
|
end.to raise_error ActiveRecord::RecordNotFound
|
|
end
|
|
|
|
scenario "raises an error if budget id is not found" do
|
|
expect do
|
|
visit admin_budget_path(0)
|
|
end.to raise_error ActiveRecord::RecordNotFound
|
|
end
|
|
|
|
end
|
|
|
|
context "Index" do
|
|
|
|
scenario "Displaying no open budgets text" do
|
|
visit admin_budgets_path
|
|
|
|
expect(page).to have_content("There are no budgets.")
|
|
end
|
|
|
|
scenario "Displaying budgets" do
|
|
budget = create(:budget)
|
|
visit admin_budgets_path
|
|
|
|
expect(page).to have_content(budget.name)
|
|
expect(page).to have_content(translated_phase_name(phase_kind: budget.phase))
|
|
end
|
|
|
|
scenario "Filters by phase" do
|
|
drafting_budget = create(:budget, :drafting)
|
|
accepting_budget = create(:budget, :accepting)
|
|
selecting_budget = create(:budget, :selecting)
|
|
balloting_budget = create(:budget, :balloting)
|
|
finished_budget = create(:budget, :finished)
|
|
|
|
visit admin_budgets_path
|
|
expect(page).to have_content(drafting_budget.name)
|
|
expect(page).to have_content(accepting_budget.name)
|
|
expect(page).to have_content(selecting_budget.name)
|
|
expect(page).to have_content(balloting_budget.name)
|
|
expect(page).not_to have_content(finished_budget.name)
|
|
|
|
click_link "Finished"
|
|
expect(page).not_to have_content(drafting_budget.name)
|
|
expect(page).not_to have_content(accepting_budget.name)
|
|
expect(page).not_to have_content(selecting_budget.name)
|
|
expect(page).not_to have_content(balloting_budget.name)
|
|
expect(page).to have_content(finished_budget.name)
|
|
|
|
click_link "Open"
|
|
expect(page).to have_content(drafting_budget.name)
|
|
expect(page).to have_content(accepting_budget.name)
|
|
expect(page).to have_content(selecting_budget.name)
|
|
expect(page).to have_content(balloting_budget.name)
|
|
expect(page).not_to have_content(finished_budget.name)
|
|
end
|
|
|
|
scenario "Open filter is properly highlighted" do
|
|
filters_links = {"current" => "Open", "finished" => "Finished"}
|
|
|
|
visit admin_budgets_path
|
|
|
|
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 admin_budgets_path(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
|
|
|
|
end
|
|
|
|
context "New" do
|
|
|
|
scenario "Create budget" do
|
|
visit admin_budgets_path
|
|
click_link "Create new budget"
|
|
|
|
fill_in "Name", with: "M30 - Summer campaign"
|
|
select "Accepting projects", from: "budget[phase]"
|
|
|
|
click_button "Create Budget"
|
|
|
|
expect(page).to have_content "New participatory budget created successfully!"
|
|
expect(page).to have_content "M30 - Summer campaign"
|
|
end
|
|
|
|
scenario "Name is mandatory" do
|
|
visit new_admin_budget_path
|
|
click_button "Create Budget"
|
|
|
|
expect(page).not_to have_content "New participatory budget created successfully!"
|
|
expect(page).to have_css("label.error", text: "Name")
|
|
end
|
|
|
|
scenario "Name should be unique" do
|
|
create(:budget, name: "Existing Name")
|
|
|
|
visit new_admin_budget_path
|
|
fill_in "Name", with: "Existing Name"
|
|
click_button "Create Budget"
|
|
|
|
expect(page).not_to have_content "New participatory budget created successfully!"
|
|
expect(page).to have_css("label.error", text: "Name")
|
|
expect(page).to have_css("small.error", text: "has already been taken")
|
|
end
|
|
|
|
end
|
|
|
|
context "Destroy" do
|
|
|
|
let!(:budget) { create(:budget) }
|
|
let(:heading) { create(:budget_heading, group: create(:budget_group, budget: budget)) }
|
|
|
|
scenario "Destroy a budget without investments" do
|
|
visit admin_budgets_path
|
|
click_link "Edit budget"
|
|
click_link "Delete budget"
|
|
|
|
expect(page).to have_content("Budget deleted successfully")
|
|
expect(page).to have_content("There are no budgets.")
|
|
end
|
|
|
|
scenario "Try to destroy a budget with investments" do
|
|
create(:budget_investment, heading: heading)
|
|
|
|
visit admin_budgets_path
|
|
click_link "Edit budget"
|
|
click_link "Delete budget"
|
|
|
|
expect(page).to have_content("You cannot delete a budget that has associated investments")
|
|
expect(page).to have_content("There is 1 budget")
|
|
end
|
|
|
|
scenario "Try to destroy a budget with polls" do
|
|
create(:poll, budget: budget)
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
click_link "Delete budget"
|
|
|
|
expect(page).to have_content("You cannot delete a budget that has an associated poll")
|
|
expect(page).to have_content("There is 1 budget")
|
|
end
|
|
end
|
|
|
|
context "Edit" do
|
|
let!(:budget) { create(:budget) }
|
|
|
|
scenario "Show phases table" do
|
|
budget.update(phase: "selecting")
|
|
|
|
visit admin_budgets_path
|
|
click_link "Edit budget"
|
|
|
|
expect(page).to have_select("budget_phase", selected: "Selecting projects")
|
|
|
|
within "#budget-phases-table" do
|
|
|
|
Budget::Phase::PHASE_KINDS.each do |phase_kind|
|
|
phase_index = Budget::Phase::PHASE_KINDS.index(phase_kind)
|
|
break if phase_kind == Budget::Phase::PHASE_KINDS.last
|
|
next_phase_kind = Budget::Phase::PHASE_KINDS[phase_index + 1]
|
|
next_phase_name = translated_phase_name(phase_kind: next_phase_kind)
|
|
expect(translated_phase_name(phase_kind: phase_kind)).to appear_before(next_phase_name)
|
|
end
|
|
|
|
budget.phases.each do |phase|
|
|
edit_phase_link = edit_admin_budget_budget_phase_path(budget, phase)
|
|
|
|
within "#budget_phase_#{phase.id}" do
|
|
expect(page).to have_content(translated_phase_name(phase_kind: phase.kind))
|
|
expect(page).to have_content("#{phase.starts_at.to_date} - #{phase.ends_at.to_date}")
|
|
expect(page).to have_css(".budget-phase-enabled.enabled")
|
|
expect(page).to have_link("Edit phase", href: edit_phase_link)
|
|
expect(page).to have_content("Active") if budget.current_phase == phase
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
scenario "Changing name for current locale will update the slug if budget is in draft phase", :js do
|
|
budget.update(phase: "drafting")
|
|
old_slug = budget.slug
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
|
|
select "Español", from: :add_language
|
|
fill_in "Name", with: "Spanish name"
|
|
click_button "Update Budget"
|
|
|
|
expect(page).to have_content "Participatory budget updated successfully"
|
|
expect(budget.reload.slug).to eq old_slug
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
|
|
select "English", from: :select_language
|
|
fill_in "Name", with: "New English Name"
|
|
click_button "Update Budget"
|
|
|
|
expect(page).to have_content "Participatory budget updated successfully"
|
|
expect(budget.reload.slug).not_to eq old_slug
|
|
expect(budget.slug).to eq "new-english-name"
|
|
end
|
|
|
|
end
|
|
|
|
context "Update" do
|
|
|
|
before do
|
|
create(:budget)
|
|
end
|
|
|
|
scenario "Update budget" do
|
|
visit admin_budgets_path
|
|
click_link "Edit budget"
|
|
|
|
fill_in "Name", with: "More trees on the streets"
|
|
click_button "Update Budget"
|
|
|
|
expect(page).to have_content("More trees on the streets")
|
|
expect(page).to have_current_path(admin_budgets_path)
|
|
end
|
|
|
|
end
|
|
|
|
context "Calculate Budget's Winner Investments" do
|
|
|
|
scenario "For a Budget in reviewing balloting", :js do
|
|
budget = create(:budget, phase: "reviewing_ballots")
|
|
group = create(:budget_group, budget: budget)
|
|
heading = create(:budget_heading, group: group, price: 4)
|
|
unselected = create(:budget_investment, :unselected, heading: heading, price: 1,
|
|
ballot_lines_count: 3)
|
|
winner = create(:budget_investment, :selected, heading: heading, price: 3,
|
|
ballot_lines_count: 2)
|
|
selected = create(:budget_investment, :selected, heading: heading, price: 2, ballot_lines_count: 1)
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
expect(page).not_to have_content "See results"
|
|
click_link "Calculate Winner Investments"
|
|
expect(page).to have_content "Winners being calculated, it may take a minute."
|
|
expect(page).to have_content winner.title
|
|
expect(page).not_to have_content unselected.title
|
|
expect(page).not_to have_content selected.title
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
expect(page).to have_content "See results"
|
|
end
|
|
|
|
scenario "For a finished Budget" do
|
|
budget = create(:budget, :finished)
|
|
allow_any_instance_of(Budget).to receive(:has_winning_investments?).and_return(true)
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
|
|
expect(page).to have_content "Calculate Winner Investments"
|
|
expect(page).to have_content "See results"
|
|
end
|
|
|
|
scenario "Recalculate for a finished Budget" do
|
|
budget = create(:budget, :finished)
|
|
group = create(:budget_group, budget: budget)
|
|
heading = create(:budget_heading, group: group)
|
|
create(:budget_investment, :winner, heading: heading)
|
|
|
|
visit edit_admin_budget_path(budget)
|
|
|
|
expect(page).to have_content "Recalculate Winner Investments"
|
|
expect(page).to have_content "See results"
|
|
expect(page).not_to have_content "Calculate Winner Investments"
|
|
|
|
visit admin_budget_budget_investments_path(budget)
|
|
click_link "Advanced filters"
|
|
check "Winners"
|
|
click_button "Filter"
|
|
|
|
expect(page).to have_content "Recalculate Winner Investments"
|
|
expect(page).not_to have_content "Calculate Winner Investments"
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
def translated_phase_name(phase_kind: kind)
|
|
I18n.t("budgets.phase.#{phase_kind}")
|
|
end
|