Refactor participatory budgets in draft mode

Previously the draft mode was a phase of the PB, but that had some
limitations.

Now the phase drafting disappears and therefore the PB can have the
status published or not published (in draft mode).

That will give more flexibility in order to navigate through the
different phases and see how it looks for administrators before
publishing the PB and everybody can see.

By default, the PB is always created in draft mode, so it gives you
the flexibility to adjust and modify anything before publishing it.
This commit is contained in:
Julian Herrero
2020-02-12 15:19:14 +07:00
committed by Javi Martín
parent 0b2b8b557d
commit 28caabecdf
21 changed files with 248 additions and 88 deletions

View File

@@ -657,6 +657,7 @@ code {
.admin-content > header { .admin-content > header {
align-items: flex-start; align-items: flex-start;
display: flex; display: flex;
flex-wrap: wrap;
a { a {
@include regular-button; @include regular-button;

View File

@@ -0,0 +1,37 @@
.admin .drafting {
margin-bottom: 2 * $line-height / 3;
margin-left: auto;
@include breakpoint(large) {
align-items: flex-start;
display: flex;
.callout {
flex: 1;
margin-bottom: 0;
}
}
@include breakpoint(small medium only) {
text-align: right;
.callout {
text-align: left;
}
}
.preview-link {
@include has-fa-icon(eye, regular);
@include hollow-button;
}
.publish-link {
@include regular-button;
margin-bottom: 0;
}
.preview-link,
.publish-link {
margin-left: $line-height / 2;
}
}

View File

@@ -0,0 +1,16 @@
<div class="drafting">
<% if can? :publish, budget %>
<div class="callout warning">
<strong><%= t("admin.budgets.edit.drafting") %></strong>
</div>
<% end %>
<%= link_to t("admin.budgets.edit.preview"), budget_path(budget), class: "preview-link", target: "_blank" %>
<% if can? :publish, budget %>
<%= link_to t("admin.budgets.edit.publish"),
publish_admin_budget_path(budget),
method: :patch, class: "publish-link",
data: { confirm: t("admin.actions.confirm") } %>
<% end %>
</div>

View File

@@ -0,0 +1,8 @@
class Admin::Budgets::DraftingComponent < ApplicationComponent
delegate :can?, to: :controller
attr_reader :budget
def initialize(budget)
@budget = budget
end
end

View File

@@ -15,6 +15,7 @@ class Admin::BudgetsController < Admin::BaseController
end end
def show def show
render :edit
end end
def new def new
@@ -23,6 +24,11 @@ class Admin::BudgetsController < Admin::BaseController
def edit def edit
end end
def publish
@budget.publish!
redirect_to edit_admin_budget_path(@budget), notice: t("admin.budgets.publish.notice")
end
def calculate_winners def calculate_winners
return unless @budget.balloting_process? return unless @budget.balloting_process?
@@ -42,9 +48,9 @@ class Admin::BudgetsController < Admin::BaseController
end end
def create def create
@budget = Budget.new(budget_params) @budget = Budget.new(budget_params.merge(published: false))
if @budget.save if @budget.save
redirect_to admin_budget_path(@budget), notice: t("admin.budgets.create.notice") redirect_to edit_admin_budget_path(@budget), notice: t("admin.budgets.create.notice")
else else
render :new render :new
end end

View File

@@ -64,7 +64,7 @@ module BudgetsHelper
end end
def budget_published?(budget) def budget_published?(budget)
!budget.drafting? || current_user&.administrator? budget.published? || current_user&.administrator?
end end
def current_budget_map_locations def current_budget_map_locations

View File

@@ -62,6 +62,7 @@ module Abilities
can :manage, Dashboard::Action can :manage, Dashboard::Action
can [:index, :read, :new, :create, :update, :destroy, :calculate_winners], Budget can [:index, :read, :new, :create, :update, :destroy, :calculate_winners], Budget
can :publish, Budget, id: Budget.drafting.ids
can [:read, :create, :update, :destroy], Budget::Group can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :admin_update, :toggle_selection], Budget::Investment can [:hide, :admin_update, :toggle_selection], Budget::Investment

View File

@@ -43,7 +43,8 @@ class Budget < ApplicationRecord
after_create :generate_phases after_create :generate_phases
scope :drafting, -> { where(phase: "drafting") } scope :published, -> { where(published: true) }
scope :drafting, -> { where.not(id: published) }
scope :informing, -> { where(phase: "informing") } scope :informing, -> { where(phase: "informing") }
scope :accepting, -> { where(phase: "accepting") } scope :accepting, -> { where(phase: "accepting") }
scope :reviewing, -> { where(phase: "reviewing") } scope :reviewing, -> { where(phase: "reviewing") }
@@ -59,7 +60,7 @@ class Budget < ApplicationRecord
scope :open, -> { where.not(phase: "finished") } scope :open, -> { where.not(phase: "finished") }
def self.current def self.current
where.not(phase: "drafting").order(:created_at).last published.order(:created_at).last
end end
def current_phase def current_phase
@@ -86,8 +87,12 @@ class Budget < ApplicationRecord
80 80
end end
def publish!
update!(published: true)
end
def drafting? def drafting?
phase == "drafting" !published?
end end
def informing? def informing?

View File

@@ -1,6 +1,6 @@
class Budget class Budget
class Phase < ApplicationRecord class Phase < ApplicationRecord
PHASE_KINDS = %w[drafting informing accepting reviewing selecting valuating publishing_prices balloting PHASE_KINDS = %w[informing accepting reviewing selecting valuating publishing_prices balloting
reviewing_ballots finished].freeze reviewing_ballots finished].freeze
PUBLISHED_PRICES_PHASES = %w[publishing_prices balloting reviewing_ballots finished].freeze PUBLISHED_PRICES_PHASES = %w[publishing_prices balloting reviewing_ballots finished].freeze
SUMMARY_MAX_LENGTH = 1000 SUMMARY_MAX_LENGTH = 1000

View File

@@ -1,5 +1,8 @@
<%= back_link_to admin_budgets_path %> <%= back_link_to admin_budgets_path %>
<h2><%= t("admin.budgets.edit.title") %></h2> <header>
<h2><%= t("admin.budgets.edit.title") %></h2>
<%= render Admin::Budgets::DraftingComponent.new(@budget) %>
</header>
<%= render "/admin/budgets/form" %> <%= render "/admin/budgets/form" %>

View File

@@ -1,5 +0,0 @@
<%= back_link_to admin_budgets_path %>
<h2><%= @budget.name %></h2>
<%= render "form" %>

View File

@@ -82,8 +82,13 @@ en:
notice: New participatory budget created successfully! notice: New participatory budget created successfully!
update: update:
notice: Participatory budget updated successfully notice: Participatory budget updated successfully
publish:
notice: "Participatory budget published successfully"
edit: edit:
title: Edit Participatory budget title: Edit Participatory budget
drafting: "This participatory budget is in draft mode, only administrators can see it in the public site. Once it's published it cannot be changed to draft mode again."
preview: "Preview budget"
publish: "Publish budget"
delete: Delete budget delete: Delete budget
phase: Phase phase: Phase
dates: Dates dates: Dates

View File

@@ -82,8 +82,13 @@ es:
notice: '¡Presupuestos participativos creados con éxito!' notice: '¡Presupuestos participativos creados con éxito!'
update: update:
notice: Presupuestos participativos actualizados notice: Presupuestos participativos actualizados
publish:
notice: "Presupuestos participativos actualizados"
edit: edit:
title: Editar presupuestos participativos title: Editar presupuestos participativos
drafting: "Este presupuesto participativo está en modo borrador, solo los administradores pueden verlo desde la parte pública de la página. Una vez se haya publicado, no se podrá volver a poner en modo borrador otra vez."
preview: "Previsualizar presupuesto"
publish: "Publicar presupuesto"
delete: Eliminar presupuesto delete: Eliminar presupuesto
phase: Fase phase: Fase
dates: Fechas dates: Fechas

View File

@@ -53,6 +53,7 @@ namespace :admin do
resources :budgets do resources :budgets do
member do member do
patch :publish
put :calculate_winners put :calculate_winners
end end

View File

@@ -0,0 +1,5 @@
class AddPublishedStatusToBudgets < ActiveRecord::Migration[5.2]
def change
add_column :budgets, :published, :boolean
end
end

View File

@@ -360,6 +360,7 @@ ActiveRecord::Schema.define(version: 2021_01_23_100638) do
t.text "description_publishing_prices" t.text "description_publishing_prices"
t.text "description_informing" t.text "description_informing"
t.string "voting_style", default: "knapsack" t.string "voting_style", default: "knapsack"
t.boolean "published"
end end
create_table "campaigns", id: :serial, force: :cascade do |t| create_table "campaigns", id: :serial, force: :cascade do |t|

View File

@@ -2,6 +2,7 @@ FactoryBot.define do
factory :budget do factory :budget do
sequence(:name) { |n| "#{Faker::Lorem.word} #{n}" } sequence(:name) { |n| "#{Faker::Lorem.word} #{n}" }
currency_symbol { "" } currency_symbol { "" }
published { true }
phase { "accepting" } phase { "accepting" }
description_drafting { "This budget is drafting" } description_drafting { "This budget is drafting" }
description_informing { "This budget is informing" } description_informing { "This budget is informing" }
@@ -15,7 +16,7 @@ FactoryBot.define do
description_finished { "This budget is finished" } description_finished { "This budget is finished" }
trait :drafting do trait :drafting do
phase { "drafting" } published { false }
end end
trait :informing do trait :informing do

View File

@@ -1,12 +1,11 @@
require "rails_helper" require "rails_helper"
describe Budget::Phase do describe Budget::Phase do
let(:budget) { create(:budget) } let(:budget) { create(:budget) }
let(:first_phase) { budget.phases.drafting } let(:informing_phase) { budget.phases.informing }
let(:second_phase) { budget.phases.informing } let(:accepting_phase) { budget.phases.accepting }
let(:third_phase) { budget.phases.accepting } let(:reviewing_phase) { budget.phases.reviewing }
let(:fourth_phase) { budget.phases.reviewing } let(:finished_phase) { budget.phases.finished }
let(:final_phase) { budget.phases.finished }
it_behaves_like "globalizable", :budget_phase it_behaves_like "globalizable", :budget_phase
@@ -31,54 +30,53 @@ describe Budget::Phase do
describe "#dates_range_valid?" do describe "#dates_range_valid?" do
it "is valid when start & end dates are different & consecutive" do it "is valid when start & end dates are different & consecutive" do
first_phase.assign_attributes(starts_at: Date.current, ends_at: Date.tomorrow) informing_phase.assign_attributes(starts_at: Date.current, ends_at: Date.tomorrow)
expect(first_phase).to be_valid expect(informing_phase).to be_valid
end end
it "is not valid when dates are equal" do it "is not valid when dates are equal" do
first_phase.assign_attributes(starts_at: Date.current, ends_at: Date.current) informing_phase.assign_attributes(starts_at: Date.current, ends_at: Date.current)
expect(first_phase).not_to be_valid expect(informing_phase).not_to be_valid
end end
it "is not valid when start date is later than end date" do it "is not valid when start date is later than end date" do
first_phase.assign_attributes(starts_at: Date.tomorrow, ends_at: Date.current) informing_phase.assign_attributes(starts_at: Date.tomorrow, ends_at: Date.current)
expect(first_phase).not_to be_valid expect(informing_phase).not_to be_valid
end end
end end
describe "#prev_phase_dates_valid?" do describe "#prev_phase_dates_valid?" do
let(:error) do let(:error) do
"Start date must be later than the start date of the previous enabled phase"\ "Start date must be later than the start date of the previous enabled phase (Information)"
" (Draft (Not visible to the public))"
end end
it "is invalid when start date is same as previous enabled phase start date" do it "is invalid when start date is same as previous enabled phase start date" do
second_phase.assign_attributes(starts_at: second_phase.prev_enabled_phase.starts_at) accepting_phase.assign_attributes(starts_at: accepting_phase.prev_enabled_phase.starts_at)
expect(second_phase).not_to be_valid expect(accepting_phase).not_to be_valid
expect(second_phase.errors.messages[:starts_at]).to include(error) expect(accepting_phase.errors.messages[:starts_at]).to include(error)
end end
it "is invalid when start date is earlier than previous enabled phase start date" do it "is invalid when start date is earlier than previous enabled phase start date" do
second_phase.assign_attributes(starts_at: second_phase.prev_enabled_phase.starts_at - 1.day) accepting_phase.assign_attributes(starts_at: accepting_phase.prev_enabled_phase.starts_at - 1.day)
expect(second_phase).not_to be_valid expect(accepting_phase).not_to be_valid
expect(second_phase.errors.messages[:starts_at]).to include(error) expect(accepting_phase.errors.messages[:starts_at]).to include(error)
end end
it "is valid when start date is in between previous enabled phase start & end dates" do it "is valid when start date is in between previous enabled phase start & end dates" do
second_phase.assign_attributes(starts_at: second_phase.prev_enabled_phase.starts_at + 1.day) accepting_phase.assign_attributes(starts_at: accepting_phase.prev_enabled_phase.starts_at + 1.day)
expect(second_phase).to be_valid expect(accepting_phase).to be_valid
end end
it "is valid when start date is later than previous enabled phase end date" do it "is valid when start date is later than previous enabled phase end date" do
second_phase.assign_attributes(starts_at: second_phase.prev_enabled_phase.ends_at + 1.day) accepting_phase.assign_attributes(starts_at: accepting_phase.prev_enabled_phase.ends_at + 1.day)
expect(second_phase).to be_valid expect(accepting_phase).to be_valid
end end
end end
@@ -88,29 +86,29 @@ describe Budget::Phase do
end end
it "is invalid when end date is same as next enabled phase end date" do it "is invalid when end date is same as next enabled phase end date" do
second_phase.assign_attributes(ends_at: second_phase.next_enabled_phase.ends_at) informing_phase.assign_attributes(ends_at: informing_phase.next_enabled_phase.ends_at)
expect(second_phase).not_to be_valid expect(informing_phase).not_to be_valid
expect(second_phase.errors.messages[:ends_at]).to include(error) expect(informing_phase.errors.messages[:ends_at]).to include(error)
end end
it "is invalid when end date is later than next enabled phase end date" do it "is invalid when end date is later than next enabled phase end date" do
second_phase.assign_attributes(ends_at: second_phase.next_enabled_phase.ends_at + 1.day) informing_phase.assign_attributes(ends_at: informing_phase.next_enabled_phase.ends_at + 1.day)
expect(second_phase).not_to be_valid expect(informing_phase).not_to be_valid
expect(second_phase.errors.messages[:ends_at]).to include(error) expect(informing_phase.errors.messages[:ends_at]).to include(error)
end end
it "is valid when end date is in between next enabled phase start & end dates" do it "is valid when end date is in between next enabled phase start & end dates" do
second_phase.assign_attributes(ends_at: second_phase.next_enabled_phase.ends_at - 1.day) informing_phase.assign_attributes(ends_at: informing_phase.next_enabled_phase.ends_at - 1.day)
expect(second_phase).to be_valid expect(informing_phase).to be_valid
end end
it "is valid when end date is earlier than next enabled phase start date" do it "is valid when end date is earlier than next enabled phase start date" do
second_phase.assign_attributes(ends_at: second_phase.next_enabled_phase.starts_at - 1.day) informing_phase.assign_attributes(ends_at: informing_phase.next_enabled_phase.starts_at - 1.day)
expect(second_phase).to be_valid expect(informing_phase).to be_valid
end end
end end
end end
@@ -128,50 +126,50 @@ describe Budget::Phase do
end end
describe "#adjust_date_ranges" do describe "#adjust_date_ranges" do
let(:prev_enabled_phase) { second_phase.prev_enabled_phase } let(:prev_enabled_phase) { accepting_phase.prev_enabled_phase }
let(:next_enabled_phase) { second_phase.next_enabled_phase } let(:next_enabled_phase) { accepting_phase.next_enabled_phase }
describe "when enabled" do describe "when enabled" do
it "adjusts previous enabled phase end date to its own start date" do it "adjusts previous enabled phase end date to its own start date" do
expect(prev_enabled_phase.ends_at).to eq(second_phase.starts_at) expect(prev_enabled_phase.ends_at).to eq(accepting_phase.starts_at)
end end
it "adjusts next enabled phase start date to its own end date" do it "adjusts next enabled phase start date to its own end date" do
expect(next_enabled_phase.starts_at).to eq(second_phase.ends_at) expect(next_enabled_phase.starts_at).to eq(accepting_phase.ends_at)
end end
end end
describe "when being enabled" do describe "when being enabled" do
before do before do
second_phase.update!(enabled: false, accepting_phase.update!(enabled: false,
starts_at: Date.current, starts_at: Date.current,
ends_at: Date.current + 2.days) ends_at: Date.current + 2.days)
end end
it "adjusts previous enabled phase end date to its own start date" do it "adjusts previous enabled phase end date to its own start date" do
expect { second_phase.update(enabled: true) } expect { accepting_phase.update(enabled: true) }
.to change { prev_enabled_phase.ends_at.to_date }.to(Date.current) .to change { prev_enabled_phase.ends_at.to_date }.to(Date.current)
end end
it "adjusts next enabled phase start date to its own end date" do it "adjusts next enabled phase start date to its own end date" do
expect do expect do
second_phase.update(enabled: true) accepting_phase.update(enabled: true)
end.to change { next_enabled_phase.starts_at.to_date }.to(Date.current + 2.days) end.to change { next_enabled_phase.starts_at.to_date }.to(Date.current + 2.days)
end end
end end
describe "when disabled" do describe "when disabled" do
before do before do
second_phase.update!(enabled: false) accepting_phase.update!(enabled: false)
end end
it "doesn't change previous enabled phase end date" do it "doesn't change previous enabled phase end date" do
expect { second_phase.update(starts_at: Date.current, ends_at: Date.current + 2.days) } expect { accepting_phase.update(starts_at: Date.current, ends_at: Date.current + 2.days) }
.not_to change { prev_enabled_phase.ends_at } .not_to change { prev_enabled_phase.ends_at }
end end
it "doesn't change next enabled phase start date" do it "doesn't change next enabled phase start date" do
expect { second_phase.update(starts_at: Date.current, ends_at: Date.current + 2.days) } expect { accepting_phase.update(starts_at: Date.current, ends_at: Date.current + 2.days) }
.not_to change { next_enabled_phase.starts_at } .not_to change { next_enabled_phase.starts_at }
end end
end end
@@ -179,7 +177,7 @@ describe Budget::Phase do
describe "when being disabled" do describe "when being disabled" do
it "doesn't adjust previous enabled phase end date to its own start date" do it "doesn't adjust previous enabled phase end date to its own start date" do
expect do expect do
second_phase.update(enabled: false, accepting_phase.update(enabled: false,
starts_at: Date.current, starts_at: Date.current,
ends_at: Date.current + 2.days) ends_at: Date.current + 2.days)
end.not_to change { prev_enabled_phase.ends_at } end.not_to change { prev_enabled_phase.ends_at }
@@ -187,7 +185,7 @@ describe Budget::Phase do
it "adjusts next enabled phase start date to its own start date" do it "adjusts next enabled phase start date to its own start date" do
expect do expect do
second_phase.update(enabled: false, accepting_phase.update(enabled: false,
starts_at: Date.current, starts_at: Date.current,
ends_at: Date.current + 2.days) ends_at: Date.current + 2.days)
end.to change { next_enabled_phase.starts_at.to_date }.to(Date.current) end.to change { next_enabled_phase.starts_at.to_date }.to(Date.current)
@@ -197,22 +195,25 @@ describe Budget::Phase do
describe "next & prev enabled phases" do describe "next & prev enabled phases" do
before do before do
second_phase.update(enabled: false) accepting_phase.update!(enabled: false)
%w[selecting reviewing_ballots balloting publishing_prices valuating].each do |phase|
budget.phases.send(phase).update(enabled: false)
end
end end
describe "#next_enabled_phase" do describe "#next_enabled_phase" do
it "returns the right next enabled phase" do it "returns the right next enabled phase" do
expect(first_phase.reload.next_enabled_phase).to eq(third_phase) expect(informing_phase.reload.next_enabled_phase).to eq(reviewing_phase)
expect(third_phase.reload.next_enabled_phase).to eq(fourth_phase) expect(reviewing_phase.reload.next_enabled_phase).to eq(finished_phase)
expect(final_phase.reload.next_enabled_phase).to eq(nil) expect(finished_phase.reload.next_enabled_phase).to eq(nil)
end end
end end
describe "#prev_enabled_phase" do describe "#prev_enabled_phase" do
it "returns the right previous enabled phase" do it "returns the right previous enabled phase" do
expect(first_phase.reload.prev_enabled_phase).to eq(nil) expect(informing_phase.reload.prev_enabled_phase).to eq(nil)
expect(third_phase.reload.prev_enabled_phase).to eq(first_phase) expect(reviewing_phase.reload.prev_enabled_phase).to eq(informing_phase)
expect(fourth_phase.reload.prev_enabled_phase).to eq(third_phase) expect(finished_phase.reload.prev_enabled_phase).to eq(reviewing_phase)
end end
end end
end end

View File

@@ -32,6 +32,36 @@ describe Budget do
expect(Budget.valuating_or_later).to be_empty expect(Budget.valuating_or_later).to be_empty
end end
end end
describe ".drafting" do
it "returns unpublished budgets" do
undefined = create(:budget, published: nil)
drafting = create(:budget, published: false)
expect(Budget.drafting).to match_array([undefined, drafting])
end
it "does not return published budgets" do
create(:budget, published: true)
expect(Budget.drafting).to be_empty
end
end
describe ".published" do
it "does not return unpublished budgets" do
create(:budget, published: nil)
create(:budget, published: false)
expect(Budget.published).to be_empty
end
it "returns published budgets" do
published = create(:budget, published: true)
expect(Budget.published).to eq [published]
end
end
end end
describe "name" do describe "name" do
@@ -96,9 +126,6 @@ describe Budget do
end end
it "produces auxiliary methods" do it "produces auxiliary methods" do
budget.phase = "drafting"
expect(budget).to be_drafting
budget.phase = "accepting" budget.phase = "accepting"
expect(budget).to be_accepting expect(budget).to be_accepting
@@ -248,7 +275,6 @@ describe Budget do
end end
describe "#generate_phases" do describe "#generate_phases" do
let(:drafting_phase) { budget.phases.drafting }
let(:informing_phase) { budget.phases.informing } let(:informing_phase) { budget.phases.informing }
let(:accepting_phase) { budget.phases.accepting } let(:accepting_phase) { budget.phases.accepting }
let(:reviewing_phase) { budget.phases.reviewing } let(:reviewing_phase) { budget.phases.reviewing }
@@ -262,7 +288,6 @@ describe Budget do
it "generates all phases linked in correct order" do it "generates all phases linked in correct order" do
expect(budget.phases.count).to eq(Budget::Phase::PHASE_KINDS.count) expect(budget.phases.count).to eq(Budget::Phase::PHASE_KINDS.count)
expect(drafting_phase.next_phase).to eq(informing_phase)
expect(informing_phase.next_phase).to eq(accepting_phase) expect(informing_phase.next_phase).to eq(accepting_phase)
expect(accepting_phase.next_phase).to eq(reviewing_phase) expect(accepting_phase.next_phase).to eq(reviewing_phase)
expect(reviewing_phase.next_phase).to eq(selecting_phase) expect(reviewing_phase.next_phase).to eq(selecting_phase)
@@ -273,8 +298,7 @@ describe Budget do
expect(reviewing_ballots_phase.next_phase).to eq(finished_phase) expect(reviewing_ballots_phase.next_phase).to eq(finished_phase)
expect(finished_phase.next_phase).to eq(nil) expect(finished_phase.next_phase).to eq(nil)
expect(drafting_phase.prev_phase).to eq(nil) expect(informing_phase.prev_phase).to eq(nil)
expect(informing_phase.prev_phase).to eq(drafting_phase)
expect(accepting_phase.prev_phase).to eq(informing_phase) expect(accepting_phase.prev_phase).to eq(informing_phase)
expect(reviewing_phase.prev_phase).to eq(accepting_phase) expect(reviewing_phase.prev_phase).to eq(accepting_phase)
expect(selecting_phase.prev_phase).to eq(reviewing_phase) expect(selecting_phase.prev_phase).to eq(reviewing_phase)

View File

@@ -15,19 +15,20 @@ describe "Admin budgets", :admin do
let!(:budget) { create(:budget, slug: "budget_slug") } let!(:budget) { create(:budget, slug: "budget_slug") }
scenario "finds budget by slug" do scenario "finds budget by slug" do
visit admin_budget_path("budget_slug") visit edit_admin_budget_path("budget_slug")
expect(page).to have_content(budget.name)
expect(page).to have_content("Edit Participatory budget")
end end
scenario "raises an error if budget slug is not found" do scenario "raises an error if budget slug is not found" do
expect do expect do
visit admin_budget_path("wrong_budget") visit edit_admin_budget_path("wrong_budget")
end.to raise_error ActiveRecord::RecordNotFound end.to raise_error ActiveRecord::RecordNotFound
end end
scenario "raises an error if budget id is not found" do scenario "raises an error if budget id is not found" do
expect do expect do
visit admin_budget_path(0) visit edit_admin_budget_path(0)
end.to raise_error ActiveRecord::RecordNotFound end.to raise_error ActiveRecord::RecordNotFound
end end
end end
@@ -107,8 +108,8 @@ describe "Admin budgets", :admin do
click_button "Create Budget" click_button "Create Budget"
expect(page).to have_content "New participatory budget created successfully!" expect(page).to have_content "New participatory budget created successfully!"
expect(page).to have_content "M30 - Summer campaign" expect(page).to have_field "Name", with: "M30 - Summer campaign"
expect(Budget.last.voting_style).to eq "knapsack" expect(page).to have_select "Final voting style", selected: "Knapsack"
end end
scenario "Create budget - Approval voting", :js do scenario "Create budget - Approval voting", :js do
@@ -161,6 +162,49 @@ describe "Admin budgets", :admin do
end end
end end
context "Create", :js do
scenario "A new budget is always created in draft mode" 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 "This participatory budget is in draft mode"
expect(page).to have_link "Preview budget"
expect(page).to have_link "Publish budget"
end
end
context "Publish", :js do
let(:budget) { create(:budget, :drafting) }
scenario "Can preview budget before it is published" do
visit edit_admin_budget_path(budget)
within_window(window_opened_by { click_link "Preview budget" }) do
expect(page).to have_current_path budget_path(budget)
end
end
scenario "Can preview a budget after it is published" do
visit edit_admin_budget_path(budget)
accept_confirm { click_link "Publish budget" }
expect(page).to have_content "Participatory budget published successfully"
expect(page).not_to have_content "This participatory budget is in draft mode"
expect(page).not_to have_link "Publish budget"
within_window(window_opened_by { click_link "Preview budget" }) do
expect(page).to have_current_path budget_path(budget)
end
end
end
context "Destroy" do context "Destroy" do
let!(:budget) { create(:budget) } let!(:budget) { create(:budget) }
let(:heading) { create(:budget_heading, budget: budget) } let(:heading) { create(:budget_heading, budget: budget) }
@@ -242,7 +286,7 @@ describe "Admin budgets", :admin do
end end
scenario "Changing name for current locale will update the slug if budget is in draft phase", :js do scenario "Changing name for current locale will update the slug if budget is in draft phase", :js do
budget.update!(phase: "drafting") budget.update!(published: false)
old_slug = budget.slug old_slug = budget.slug
visit edit_admin_budget_path(budget) visit edit_admin_budget_path(budget)

View File

@@ -168,7 +168,7 @@ describe "Budgets" do
scenario "Not show investment links earlier of balloting " do scenario "Not show investment links earlier of balloting " do
budget = create(:budget) budget = create(:budget)
create(:budget_heading, budget: budget) create(:budget_heading, budget: budget)
phases_without_links = ["drafting", "informing"] phases_without_links = ["informing"]
not_allowed_phase_list = Budget::Phase::PHASE_KINDS - not_allowed_phase_list = Budget::Phase::PHASE_KINDS -
phases_without_links - phases_without_links -
allowed_phase_list allowed_phase_list
@@ -205,9 +205,10 @@ describe "Budgets" do
scenario "Index shows only published phases" do scenario "Index shows only published phases" do
budget.update!(phase: :finished) budget.update!(phase: :finished)
phases = budget.phases phases = budget.phases
phases.drafting.update!(starts_at: "30-12-2017", ends_at: "31-12-2017", enabled: true,
description: "Description of drafting phase", phases.informing.update!(starts_at: "30-12-2017", ends_at: "31-12-2017", enabled: true,
summary: "<p>This is the summary for drafting phase</p>") description: "Description of informing phase",
summary: "<p>This is the summary for informing phase</p>")
phases.accepting.update!(starts_at: "01-01-2018", ends_at: "10-01-2018", enabled: true, phases.accepting.update!(starts_at: "01-01-2018", ends_at: "10-01-2018", enabled: true,
description: "Description of accepting phase", description: "Description of accepting phase",
@@ -243,8 +244,6 @@ describe "Budgets" do
visit budgets_path visit budgets_path
expect(page).not_to have_content "This is the summary for drafting phase"
expect(page).not_to have_content "December 30, 2017 - December 31, 2017"
expect(page).not_to have_content "This is the summary for reviewing phase" expect(page).not_to have_content "This is the summary for reviewing phase"
expect(page).not_to have_content "January 11, 2018 - January 20, 2018" expect(page).not_to have_content "January 11, 2018 - January 20, 2018"
expect(page).not_to have_content "This is the summary for valuating phase" expect(page).not_to have_content "This is the summary for valuating phase"
@@ -254,6 +253,8 @@ describe "Budgets" do
expect(page).not_to have_content "This is the summary for reviewing_ballots phase" expect(page).not_to have_content "This is the summary for reviewing_ballots phase"
expect(page).not_to have_content "March 11, 2018 - March 20, 2018" expect(page).not_to have_content "March 11, 2018 - March 20, 2018"
expect(page).to have_content "This is the summary for informing phase"
expect(page).to have_content "December 30, 2017 - December 31, 2017"
expect(page).to have_content "This is the summary for accepting phase" expect(page).to have_content "This is the summary for accepting phase"
expect(page).to have_content "January 01, 2018 - January 20, 2018" expect(page).to have_content "January 01, 2018 - January 20, 2018"
expect(page).to have_content "This is the summary for selecting phase" expect(page).to have_content "This is the summary for selecting phase"
@@ -478,7 +479,7 @@ describe "Budgets" do
before do before do
logout logout
budget.update!(phase: "drafting") budget.update!(published: false)
create(:budget) create(:budget)
end end