diff --git a/app/assets/stylesheets/admin/budgets_wizard/headings/group_switcher.scss b/app/assets/stylesheets/admin/budgets_wizard/headings/group_switcher.scss
new file mode 100644
index 000000000..e0c4109f3
--- /dev/null
+++ b/app/assets/stylesheets/admin/budgets_wizard/headings/group_switcher.scss
@@ -0,0 +1,50 @@
+.budget-group-switcher {
+ margin-bottom: $line-height;
+
+ p {
+ margin-bottom: 0;
+ }
+
+ > .menu > li {
+
+ > button {
+ align-items: center;
+ border: $admin-border;
+ border-radius: $button-radius;
+ display: inline-flex;
+ padding: rem-calc(11) rem-calc(16);
+
+ &:active {
+ color: inherit;
+ }
+
+ &::after {
+ @include css-triangle($dropdownmenu-arrow-size, currentcolor, down);
+ margin-left: 0.2em;
+ }
+ }
+ }
+
+ .menu.is-dropdown-submenu {
+ margin: 0;
+ min-width: 100%;
+ padding: 0;
+
+ li {
+ margin-bottom: 0;
+ }
+
+ a {
+ cursor: default;
+ padding: rem-calc(11) rem-calc(16);
+ width: 100%;
+
+ &:focus,
+ &:hover {
+ @include brand-background;
+ text-decoration: none;
+ outline: none;
+ }
+ }
+ }
+}
diff --git a/app/components/admin/budget_groups/groups_component.html.erb b/app/components/admin/budget_groups/groups_component.html.erb
index 00bcc18fc..2b8f1d596 100644
--- a/app/components/admin/budget_groups/groups_component.html.erb
+++ b/app/components/admin/budget_groups/groups_component.html.erb
@@ -18,7 +18,7 @@
<%= render Admin::TableActionsComponent.new(group) do |actions| %>
<%= actions.link_to t("admin.budget_groups.headings_manage"),
- admin_budget_group_headings_path(budget, group),
+ headings_path(actions, group),
class: "headings-link" %>
<% end %>
|
diff --git a/app/components/admin/budget_groups/groups_component.rb b/app/components/admin/budget_groups/groups_component.rb
index 87012734d..51bf60649 100644
--- a/app/components/admin/budget_groups/groups_component.rb
+++ b/app/components/admin/budget_groups/groups_component.rb
@@ -10,4 +10,8 @@ class Admin::BudgetGroups::GroupsComponent < ApplicationComponent
def budget
@budget ||= groups.first.budget
end
+
+ def headings_path(table_actions_component, group)
+ send("#{table_actions_component.namespace}_budget_group_headings_path", group.budget, group)
+ end
end
diff --git a/app/components/admin/budgets_wizard/creation_step_component.html.erb b/app/components/admin/budgets_wizard/creation_step_component.html.erb
new file mode 100644
index 000000000..b6ecad267
--- /dev/null
+++ b/app/components/admin/budgets_wizard/creation_step_component.html.erb
@@ -0,0 +1,19 @@
+
+
+
+ <%= content %>
+
+
+
+ <% if next_step_path %>
+ <%= link_to t("admin.budgets_wizard.#{i18n_namespace}.continue"),
+ next_step_path,
+ class: "next-step" %>
+ <% else %>
+
+ <%= t("admin.budgets_wizard.#{i18n_namespace}.continue") %>
+
+ <% end %>
+
diff --git a/app/components/admin/budgets_wizard/creation_step_component.rb b/app/components/admin/budgets_wizard/creation_step_component.rb
new file mode 100644
index 000000000..2bd220146
--- /dev/null
+++ b/app/components/admin/budgets_wizard/creation_step_component.rb
@@ -0,0 +1,22 @@
+class Admin::BudgetsWizard::CreationStepComponent < ApplicationComponent
+ attr_reader :record, :next_step_path
+
+ def initialize(record, next_step_path)
+ @record = record
+ @next_step_path = next_step_path
+ end
+
+ private
+
+ def show_form?
+ record.errors.any?
+ end
+
+ def i18n_namespace
+ i18n_namespace_with_budget.gsub("budget_", "")
+ end
+
+ def i18n_namespace_with_budget
+ record.class.table_name
+ end
+end
diff --git a/app/components/admin/budgets_wizard/creation_timeline_component.rb b/app/components/admin/budgets_wizard/creation_timeline_component.rb
index 6db8d61e2..a4f4ed24f 100644
--- a/app/components/admin/budgets_wizard/creation_timeline_component.rb
+++ b/app/components/admin/budgets_wizard/creation_timeline_component.rb
@@ -8,6 +8,6 @@ class Admin::BudgetsWizard::CreationTimelineComponent < ApplicationComponent
private
def steps
- %w[budget groups]
+ %w[budget groups headings]
end
end
diff --git a/app/components/admin/budgets_wizard/groups/creation_step_component.html.erb b/app/components/admin/budgets_wizard/groups/creation_step_component.html.erb
index a4254e09e..9f1c1ab33 100644
--- a/app/components/admin/budgets_wizard/groups/creation_step_component.html.erb
+++ b/app/components/admin/budgets_wizard/groups/creation_step_component.html.erb
@@ -1,19 +1,3 @@
-
-
-
+<%= render Admin::BudgetsWizard::CreationStepComponent.new(group, next_step_path) do %>
<%= render "/admin/budget_groups/form", group: group, path: form_path, action: "create" %>
-
-
-
- <% if next_step_path %>
- <%= link_to t("admin.budgets_wizard.groups.continue"),
- next_step_path,
- class: "next-step" %>
- <% else %>
-
- <%= t("admin.budgets_wizard.groups.continue") %>
-
- <% end %>
-
+<% end %>
diff --git a/app/components/admin/budgets_wizard/groups/creation_step_component.rb b/app/components/admin/budgets_wizard/groups/creation_step_component.rb
index 00a6cb2d3..8a5e3bfa9 100644
--- a/app/components/admin/budgets_wizard/groups/creation_step_component.rb
+++ b/app/components/admin/budgets_wizard/groups/creation_step_component.rb
@@ -12,16 +12,12 @@ class Admin::BudgetsWizard::Groups::CreationStepComponent < ApplicationComponent
group.budget
end
- def show_form?
- group.errors.any?
- end
-
def form_path
admin_budgets_wizard_budget_groups_path(budget)
end
def next_step_path
- admin_budget_group_headings_path(budget, next_step_group) if next_step_enabled?
+ admin_budgets_wizard_budget_group_headings_path(budget, next_step_group) if next_step_enabled?
end
def next_step_enabled?
diff --git a/app/components/admin/budgets_wizard/headings/creation_step_component.html.erb b/app/components/admin/budgets_wizard/headings/creation_step_component.html.erb
new file mode 100644
index 000000000..a8ca3d7b4
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/creation_step_component.html.erb
@@ -0,0 +1,3 @@
+<%= render Admin::BudgetsWizard::CreationStepComponent.new(heading, next_step_path) do %>
+ <%= render "/admin/budget_headings/form", heading: heading, path: form_path, action: "create" %>
+<% end %>
diff --git a/app/components/admin/budgets_wizard/headings/creation_step_component.rb b/app/components/admin/budgets_wizard/headings/creation_step_component.rb
new file mode 100644
index 000000000..8758c6bbc
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/creation_step_component.rb
@@ -0,0 +1,25 @@
+class Admin::BudgetsWizard::Headings::CreationStepComponent < ApplicationComponent
+ attr_reader :heading
+
+ def initialize(heading)
+ @heading = heading
+ end
+
+ private
+
+ def budget
+ heading.budget
+ end
+
+ def form_path
+ admin_budgets_wizard_budget_group_headings_path(heading.group.budget, heading.group)
+ end
+
+ def next_step_path
+ admin_budget_path(budget) if next_step_enabled?
+ end
+
+ def next_step_enabled?
+ budget.headings.any?
+ end
+end
diff --git a/app/components/admin/budgets_wizard/headings/edit_component.html.erb b/app/components/admin/budgets_wizard/headings/edit_component.html.erb
new file mode 100644
index 000000000..5a269b582
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/edit_component.html.erb
@@ -0,0 +1,7 @@
+<%= back_link_to admin_budgets_wizard_budget_group_headings_path(budget, group) %>
+
+<%= header %>
+
+<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("headings") %>
+
+<%= render "/admin/budget_headings/form", heading: heading, path: form_path, action: "submit" %>
diff --git a/app/components/admin/budgets_wizard/headings/edit_component.rb b/app/components/admin/budgets_wizard/headings/edit_component.rb
new file mode 100644
index 000000000..ee6250b23
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/edit_component.rb
@@ -0,0 +1,26 @@
+class Admin::BudgetsWizard::Headings::EditComponent < ApplicationComponent
+ include Header
+ attr_reader :heading
+
+ def initialize(heading)
+ @heading = heading
+ end
+
+ def budget
+ heading.budget
+ end
+
+ def group
+ heading.group
+ end
+
+ def title
+ heading.name
+ end
+
+ private
+
+ def form_path
+ admin_budgets_wizard_budget_group_heading_path(budget, group, heading)
+ end
+end
diff --git a/app/components/admin/budgets_wizard/headings/group_switcher_component.html.erb b/app/components/admin/budgets_wizard/headings/group_switcher_component.html.erb
new file mode 100644
index 000000000..4fe2ba830
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/group_switcher_component.html.erb
@@ -0,0 +1,21 @@
+
+ <% if other_groups.one? %>
+
+ <%= t("admin.budget_headings.group_switcher.currently_showing", group: group.name) %>
+ <%= link_to t("admin.budget_headings.group_switcher.the_other_group", group: other_groups.first.name),
+ headings_path(other_groups.first) %>
+
+ <% else %>
+
<%= t("admin.budget_headings.group_switcher.currently_showing", group: group.name) %>
+
+ <% end %>
+
diff --git a/app/components/admin/budgets_wizard/headings/group_switcher_component.rb b/app/components/admin/budgets_wizard/headings/group_switcher_component.rb
new file mode 100644
index 000000000..b6e490ad9
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/group_switcher_component.rb
@@ -0,0 +1,25 @@
+class Admin::BudgetsWizard::Headings::GroupSwitcherComponent < ApplicationComponent
+ attr_reader :group
+
+ def initialize(group)
+ @group = group
+ end
+
+ def render?
+ other_groups.any?
+ end
+
+ private
+
+ def budget
+ group.budget
+ end
+
+ def other_groups
+ @other_groups ||= budget.groups.sort_by_name - [group]
+ end
+
+ def headings_path(group)
+ admin_budgets_wizard_budget_group_headings_path(budget, group)
+ end
+end
diff --git a/app/components/admin/budgets_wizard/headings/index_component.html.erb b/app/components/admin/budgets_wizard/headings/index_component.html.erb
new file mode 100644
index 000000000..21e0d538d
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/index_component.html.erb
@@ -0,0 +1,10 @@
+<%= back_link_to admin_budgets_wizard_budget_groups_path(budget), t("admin.budget_headings.index.back") %>
+
+<%= header %>
+
+<%= render Admin::Budgets::HelpComponent.new("budget_headings") %>
+<%= render Admin::BudgetsWizard::CreationTimelineComponent.new("headings") %>
+
+<%= render Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group) %>
+<%= render Admin::BudgetHeadings::HeadingsComponent.new(headings) %>
+<%= render Admin::BudgetsWizard::Headings::CreationStepComponent.new(new_heading) %>
diff --git a/app/components/admin/budgets_wizard/headings/index_component.rb b/app/components/admin/budgets_wizard/headings/index_component.rb
new file mode 100644
index 000000000..76aa584a9
--- /dev/null
+++ b/app/components/admin/budgets_wizard/headings/index_component.rb
@@ -0,0 +1,21 @@
+class Admin::BudgetsWizard::Headings::IndexComponent < ApplicationComponent
+ include Header
+ attr_reader :headings, :new_heading
+
+ def initialize(headings, new_heading)
+ @headings = headings
+ @new_heading = new_heading
+ end
+
+ def budget
+ group.budget
+ end
+
+ def group
+ new_heading.group
+ end
+
+ def title
+ t("admin.budget_headings.index.title", budget: budget.name, group: group.name)
+ end
+end
diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb
index 6c0f43174..366641a8a 100644
--- a/app/controllers/admin/budget_headings_controller.rb
+++ b/app/controllers/admin/budget_headings_controller.rb
@@ -1,69 +1,20 @@
class Admin::BudgetHeadingsController < Admin::BaseController
- include Translatable
- include FeatureFlags
- feature_flag :budgets
-
- before_action :load_budget
- before_action :load_group
- before_action :load_heading, only: [:edit, :update, :destroy]
+ include Admin::BudgetHeadingsActions
def index
- @headings = @group.headings.order(:id)
end
def new
@heading = @group.headings.new
end
- def edit
- end
-
- def create
- @heading = @group.headings.new(budget_heading_params)
- if @heading.save
- redirect_to headings_index, notice: t("admin.budget_headings.create.notice")
- else
- render :new
- end
- end
-
- def update
- if @heading.update(budget_heading_params)
- redirect_to headings_index, notice: t("admin.budget_headings.update.notice")
- else
- render :edit
- end
- end
-
- def destroy
- if @heading.can_be_deleted?
- @heading.destroy!
- redirect_to headings_index, notice: t("admin.budget_headings.destroy.success_notice")
- else
- redirect_to headings_index, alert: t("admin.budget_headings.destroy.unable_notice")
- end
- end
-
private
- def load_budget
- @budget = Budget.find_by_slug_or_id! params[:budget_id]
- end
-
- def load_group
- @group = @budget.groups.find_by_slug_or_id! params[:group_id]
- end
-
- def load_heading
- @heading = @group.headings.find_by_slug_or_id! params[:id]
- end
-
def headings_index
admin_budget_group_headings_path(@budget, @group)
end
- def budget_heading_params
- valid_attributes = [:price, :population, :allow_custom_content, :latitude, :longitude, :max_ballot_lines]
- params.require(:budget_heading).permit(*valid_attributes, translation_params(Budget::Heading))
+ def new_action
+ :new
end
end
diff --git a/app/controllers/admin/budgets_wizard/headings_controller.rb b/app/controllers/admin/budgets_wizard/headings_controller.rb
new file mode 100644
index 000000000..5eb78e5d3
--- /dev/null
+++ b/app/controllers/admin/budgets_wizard/headings_controller.rb
@@ -0,0 +1,19 @@
+class Admin::BudgetsWizard::HeadingsController < Admin::BaseController
+ include Admin::BudgetHeadingsActions
+
+ before_action :load_headings, only: [:index, :create]
+
+ def index
+ @heading = @group.headings.new
+ end
+
+ private
+
+ def headings_index
+ admin_budgets_wizard_budget_group_headings_path(@budget, @group)
+ end
+
+ def new_action
+ :index
+ end
+end
diff --git a/app/controllers/concerns/admin/budget_headings_actions.rb b/app/controllers/concerns/admin/budget_headings_actions.rb
new file mode 100644
index 000000000..4bc125288
--- /dev/null
+++ b/app/controllers/concerns/admin/budget_headings_actions.rb
@@ -0,0 +1,66 @@
+module Admin::BudgetHeadingsActions
+ extend ActiveSupport::Concern
+
+ included do
+ include Translatable
+ include FeatureFlags
+ feature_flag :budgets
+
+ before_action :load_budget
+ before_action :load_group
+ before_action :load_headings, only: :index
+ before_action :load_heading, only: [:edit, :update, :destroy]
+ end
+
+ def edit
+ end
+
+ def create
+ @heading = @group.headings.new(budget_heading_params)
+ if @heading.save
+ redirect_to headings_index, notice: t("admin.budget_headings.create.notice")
+ else
+ render new_action
+ end
+ end
+
+ def update
+ if @heading.update(budget_heading_params)
+ redirect_to headings_index, notice: t("admin.budget_headings.update.notice")
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ if @heading.can_be_deleted?
+ @heading.destroy!
+ redirect_to headings_index, notice: t("admin.budget_headings.destroy.success_notice")
+ else
+ redirect_to headings_index, alert: t("admin.budget_headings.destroy.unable_notice")
+ end
+ end
+
+ private
+
+ def load_budget
+ @budget = Budget.find_by_slug_or_id! params[:budget_id]
+ end
+
+ def load_group
+ @group = @budget.groups.find_by_slug_or_id! params[:group_id]
+ end
+
+ def load_headings
+ @headings = @group.headings.order(:id)
+ end
+
+ def load_heading
+ @heading = @group.headings.find_by_slug_or_id! params[:id]
+ end
+
+ def budget_heading_params
+ valid_attributes = [:price, :population, :allow_custom_content, :latitude, :longitude, :max_ballot_lines]
+ params.require(:budget_heading).permit(*valid_attributes, translation_params(Budget::Heading))
+ end
+end
diff --git a/app/views/admin/budgets_wizard/headings/edit.html.erb b/app/views/admin/budgets_wizard/headings/edit.html.erb
new file mode 100644
index 000000000..63deb1260
--- /dev/null
+++ b/app/views/admin/budgets_wizard/headings/edit.html.erb
@@ -0,0 +1 @@
+<%= render Admin::BudgetsWizard::Headings::EditComponent.new(@heading) %>
diff --git a/app/views/admin/budgets_wizard/headings/index.html.erb b/app/views/admin/budgets_wizard/headings/index.html.erb
new file mode 100644
index 000000000..ed647b65a
--- /dev/null
+++ b/app/views/admin/budgets_wizard/headings/index.html.erb
@@ -0,0 +1 @@
+<%= render Admin::BudgetsWizard::Headings::IndexComponent.new(@headings, @heading) %>
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index e2d8ee8e8..5fee91c88 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -148,6 +148,7 @@ ignore_unused:
- "admin.budgets.index.filter*"
- "admin.budgets.edit.(administrators|valuators).*"
- "admin.budget_groups.index.*.help_block"
+ - "admin.budget_headings.index.*.help_block"
- "admin.budget_investments.index.filter*"
- "admin.organizations.index.filter*"
- "admin.hidden_users.index.filter*"
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml
index ec67b8e09..427faae50 100644
--- a/config/locales/en/admin.yml
+++ b/config/locales/en/admin.yml
@@ -177,9 +177,14 @@ en:
create: "Create new heading"
edit: "Edit heading"
submit: "Save heading"
+ group_switcher:
+ currently_showing: "Showing headings from the %{group} group."
+ different_group: "Manage headings from a different group"
+ the_other_group: "Manage headings from the %{group} group."
index:
back: "Go back to groups"
help: "Headings are meant to divide the money of the participatory budget. Here you can add headings for this group and assign the amount of money that will be used for each heading."
+ new_button: "Add new heading"
title: "%{budget} / %{group} headings"
budget_phases:
edit:
@@ -290,10 +295,13 @@ en:
creation_timeline:
budget: Budget
groups: Groups
+ headings: Headings
budgets:
continue: "Continue to groups"
groups:
continue: "Continue to headings"
+ headings:
+ continue: "Continue to phases"
milestones:
index:
table_id: "ID"
diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml
index 7feb7440f..b6b2d06d5 100644
--- a/config/locales/es/admin.yml
+++ b/config/locales/es/admin.yml
@@ -177,9 +177,14 @@ es:
create: "Crear nueva partida"
edit: "Editar partida"
submit: "Guardar partida"
+ group_switcher:
+ currently_showing: "Mostrando las partidas del grupo: %{group}"
+ different_group: "Ir a partidas de otro grupo"
+ the_other_group: "Ir a partidas del grupo %{group}."
index:
back: "Volver a grupos"
help: "Las partidas sirven para dividir el dinero del presupuesto participativo. Aquí puedes ir añadiendo partidas para cada grupo y establecer la cantidad de dinero que se gastará en cada partida."
+ new_button: "Añadir una partida nueva"
title: "Partidas de %{budget} / %{group}"
budget_phases:
edit:
@@ -290,10 +295,13 @@ es:
creation_timeline:
budget: Presupuesto
groups: Grupos
+ headings: Partidas
budgets:
continue: "Continuar a grupos"
groups:
continue: "Continuar a partidas"
+ headings:
+ continue: "Continuar a fases"
milestones:
index:
table_id: "ID"
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index 846bb8635..bb28dfa0f 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -74,7 +74,9 @@ namespace :admin do
namespace :budgets_wizard do
resources :budgets, only: [:create, :new] do
- resources :groups, only: [:index, :create, :edit, :update, :destroy]
+ resources :groups, only: [:index, :create, :edit, :update, :destroy] do
+ resources :headings, only: [:index, :create, :edit, :update, :destroy]
+ end
end
end
diff --git a/spec/components/admin/budgets_wizard/headings/group_switcher_component_spec.rb b/spec/components/admin/budgets_wizard/headings/group_switcher_component_spec.rb
new file mode 100644
index 000000000..140db350d
--- /dev/null
+++ b/spec/components/admin/budgets_wizard/headings/group_switcher_component_spec.rb
@@ -0,0 +1,41 @@
+require "rails_helper"
+
+describe Admin::BudgetsWizard::Headings::GroupSwitcherComponent, type: :component do
+ it "is not rendered for budgets with one group" do
+ group = create(:budget_group, budget: create(:budget))
+
+ render_inline Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group)
+
+ expect(page.text).to be_empty
+ expect(page).not_to have_css ".budget-group-switcher"
+ end
+
+ it "renders a link to switch group for budgets with two groups" do
+ budget = create(:budget)
+ group = create(:budget_group, budget: budget, name: "Parks")
+ create(:budget_group, budget: budget, name: "Recreation")
+
+ render_inline Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group)
+
+ expect(page).to have_content "Showing headings from the Parks group"
+ expect(page).to have_link "Manage headings from the Recreation group."
+ expect(page).not_to have_css "ul"
+ end
+
+ it "renders a menu to switch group for budgets with more than two groups" do
+ budget = create(:budget)
+ group = create(:budget_group, budget: budget, name: "Parks")
+ create(:budget_group, budget: budget, name: "Recreation")
+ create(:budget_group, budget: budget, name: "Entertainment")
+
+ render_inline Admin::BudgetsWizard::Headings::GroupSwitcherComponent.new(group)
+
+ expect(page).to have_content "Showing headings from the Parks group"
+ expect(page).to have_button "Manage headings from a different group"
+
+ within "button + ul" do
+ expect(page).to have_link "Recreation"
+ expect(page).to have_link "Entertainment"
+ end
+ end
+end
diff --git a/spec/system/admin/budgets_wizard/headings_spec.rb b/spec/system/admin/budgets_wizard/headings_spec.rb
new file mode 100644
index 000000000..d3823347e
--- /dev/null
+++ b/spec/system/admin/budgets_wizard/headings_spec.rb
@@ -0,0 +1,148 @@
+require "rails_helper"
+
+describe "Budgets wizard, headings step", :admin do
+ let(:budget) { create(:budget, :drafting) }
+ let(:group) { create(:budget_group, budget: budget, name: "Default group") }
+
+ describe "Index" do
+ scenario "back to a previous step" do
+ visit admin_budgets_wizard_budget_group_headings_path(budget, group)
+
+ within "#side_menu" do
+ expect(page).to have_css ".is-active", exact_text: "Participatory budgets"
+ end
+
+ click_link "Go back to groups"
+
+ expect(page).to have_css "tr", text: "Default group"
+ expect(page).to have_css ".creation-timeline"
+ end
+
+ scenario "change to another group" do
+ economy = create(:budget_group, budget: budget, name: "Economy")
+ health = create(:budget_group, budget: budget, name: "Health")
+ create(:budget_group, budget: budget, name: "Technology")
+
+ create(:budget_heading, group: economy, name: "Banking")
+ create(:budget_heading, group: health, name: "Hospitals")
+
+ visit admin_budgets_wizard_budget_group_headings_path(budget, economy)
+
+ within(".heading") do
+ expect(page).to have_content "Banking"
+ expect(page).not_to have_content "Hospitals"
+ end
+
+ expect(page).not_to have_link "Health"
+
+ click_button "Manage headings from a different group"
+ click_link "Health"
+
+ within(".heading") do
+ expect(page).to have_content "Hospitals"
+ expect(page).not_to have_content "Banking"
+ end
+ expect(page).to have_css ".creation-timeline"
+ end
+ end
+
+ describe "New" do
+ scenario "cancel creating a heading" do
+ visit admin_budgets_wizard_budget_group_headings_path(budget, group)
+
+ expect(page).not_to have_field "Heading name"
+ expect(page).not_to have_button "Cancel"
+ expect(page).to have_content "Continue to phases"
+
+ click_button "Add new heading"
+
+ expect(page).to have_field "Heading name"
+ expect(page).not_to have_button "Add new heading"
+ expect(page).not_to have_content "Continue to phases"
+
+ click_button "Cancel"
+
+ expect(page).to have_button "Add new heading"
+ expect(page).not_to have_field "Heading name"
+ expect(page).not_to have_button "Cancel"
+ expect(page).to have_content "Continue to phases"
+ end
+
+ scenario "submit the form with errors" do
+ visit admin_budgets_wizard_budget_group_headings_path(budget, group)
+ click_button "Add new heading"
+
+ click_button "Create new heading"
+
+ expect(page).not_to have_content "Heading created successfully!"
+ expect(page).to have_css(".is-invalid-label", text: "Heading name")
+ expect(page).to have_content "can't be blank"
+ expect(page).to have_button "Create new heading"
+ expect(page).to have_button "Cancel"
+ expect(page).not_to have_button "Add new heading"
+ expect(page).not_to have_content "Continue to phases"
+ end
+ end
+
+ describe "Edit" do
+ scenario "update heading" do
+ create(:budget_heading, group: group, name: "Heading wiht a typo")
+
+ visit admin_budgets_wizard_budget_group_headings_path(budget, group)
+
+ expect(page).to have_css ".creation-timeline"
+
+ within("tr", text: "Heading wiht a typo") { click_link "Edit" }
+ fill_in "Heading name", with: "Heading without typos"
+ click_button "Save heading"
+
+ expect(page).to have_content "Heading updated successfully"
+ expect(page).to have_css ".creation-timeline"
+ expect(page).to have_css "td", exact_text: "Heading without typos"
+ end
+
+ scenario "submit the form with errors and then without errors" do
+ heading = create(:budget_heading, group: group, name: "Heading wiht a typo")
+
+ visit edit_admin_budgets_wizard_budget_group_heading_path(budget, group, heading)
+ fill_in "Heading name", with: ""
+ click_button "Save heading"
+
+ expect(page).to have_css "#error_explanation"
+ expect(page).to have_css ".creation-timeline"
+
+ fill_in "Heading name", with: "Heading without typos"
+ click_button "Save heading"
+
+ expect(page).to have_content "Heading updated successfully"
+ expect(page).to have_css ".creation-timeline"
+ expect(page).to have_css "td", exact_text: "Heading without typos"
+ end
+ end
+
+ describe "Destroy" do
+ scenario "delete a heading without investments" do
+ create(:budget_heading, group: group, name: "Delete me!")
+
+ visit admin_budgets_wizard_budget_group_headings_path(budget, group)
+ within("tr", text: "Delete me!") { accept_confirm { click_link "Delete" } }
+
+ expect(page).to have_content "Heading deleted successfully"
+ expect(page).not_to have_content "Delete me!"
+ expect(page).to have_css ".creation-timeline"
+ end
+
+ scenario "try to delete a heading with investments" do
+ heading = create(:budget_heading, group: group, name: "Don't delete me!")
+ create(:budget_investment, heading: heading)
+
+ visit admin_budgets_wizard_budget_group_headings_path(budget, group)
+
+ within("tr", text: "Don't delete me!") { accept_confirm { click_link "Delete" } }
+
+ expect(page).to have_content "You cannot delete a Heading that has associated investments"
+ expect(page).to have_content "Don't delete me!"
+ expect(page).to have_css ".creation-timeline"
+ end
+ end
+end