From 2b709f1a36eec9b5628b4b4e1869e615bb4a7d05 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Tue, 24 Mar 2020 07:20:22 +0100 Subject: [PATCH] Groups and headings CRUD from budget view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before, users needed to navigate to the list of groups in order to add, edit or delete a group. Also, they need to navigate to the list of groups first, and then to the list of headings for that group in order to add, edit or delete a heading. Now, it's possible to do all these actions for any group or heading from the participatory budget view to bring simplicity and to reduce the number of clicks from a user perspective. Co-Authored-By: Javi Martín --- .../admin/budgets/groups_and_headings.scss | 92 +++++++++++++++++ .../stylesheets/admin/budgets/show.scss | 4 + .../stylesheets/admin/table_actions.scss | 18 +--- .../budgets/groups_and_headings.scss | 2 +- app/assets/stylesheets/mixins/icons.scss | 19 ++++ app/components/admin/action_component.rb | 8 +- .../headings_component.html.erb | 3 +- .../groups_and_headings_component.html.erb | 26 +++++ .../budgets/groups_and_headings_component.rb | 13 +++ .../admin/budgets/show_component.html.erb | 5 + .../budgets/table_actions_component.html.erb | 3 - .../phases/index_component.html.erb | 2 +- .../admin/table_actions_component.rb | 2 +- .../admin/budget_groups_controller.rb | 7 +- .../admin/budget_headings_controller.rb | 5 +- .../budgets_wizard/headings_controller.rb | 4 + .../concerns/admin/budget_headings_actions.rb | 5 - .../admin/budget_groups/_header.html.erb | 2 +- app/views/admin/budget_groups/index.html.erb | 11 --- .../admin/budget_headings/_header.html.erb | 2 +- .../admin/budget_headings/index.html.erb | 9 -- config/locales/en/admin.yml | 9 +- config/locales/es/admin.yml | 9 +- config/routes/admin.rb | 4 +- .../budgets/table_actions_component_spec.rb | 5 +- .../admin/budget_groups_controller_spec.rb | 4 +- .../admin/budget_headings_controller_spec.rb | 2 +- spec/system/admin/budget_groups_spec.rb | 98 ++++++++----------- spec/system/admin/budget_headings_spec.rb | 92 ++++++++--------- .../admin/budgets_wizard/groups_spec.rb | 7 +- .../admin/budgets_wizard/headings_spec.rb | 7 +- .../admin/budgets_wizard/phases_spec.rb | 2 +- .../admin/budgets_wizard/wizard_spec.rb | 51 ++++------ 33 files changed, 309 insertions(+), 223 deletions(-) create mode 100644 app/assets/stylesheets/admin/budgets/groups_and_headings.scss create mode 100644 app/components/admin/budgets/groups_and_headings_component.html.erb create mode 100644 app/components/admin/budgets/groups_and_headings_component.rb delete mode 100644 app/views/admin/budget_groups/index.html.erb delete mode 100644 app/views/admin/budget_headings/index.html.erb diff --git a/app/assets/stylesheets/admin/budgets/groups_and_headings.scss b/app/assets/stylesheets/admin/budgets/groups_and_headings.scss new file mode 100644 index 000000000..78a4e49c3 --- /dev/null +++ b/app/assets/stylesheets/admin/budgets/groups_and_headings.scss @@ -0,0 +1,92 @@ +.admin .groups-and-headings { + $gap: rem-calc(map-get($grid-column-gutter, medium)); + + > section + section { + margin-top: $line-height * 1.5; + } + + > section { + display: flex; + flex-wrap: wrap; + } + + h4 { + margin-#{$global-right}: $gap; + } + + dl, + .callout { + width: 100%; + } + + dt, + dd { + display: inline; + } + + dt { + font-weight: normal; + } + + dd { + font-weight: bold; + } + + th:last-child { + text-align: $global-right; + } + + .table-actions { + justify-content: flex-end; + } + + .groups-actions { + @include flex-with-gap($gap); + align-items: flex-start; + flex: 1; + margin-bottom: $line-height / 2; + + .edit-link, + .destroy-link { + @include icon-on-top; + } + + .edit-link { + @include has-fa-icon(edit, regular); + } + + .destroy-link { + @include has-fa-icon(trash-alt, regular); + color: darken($alert-color, 5%); + } + + .new-link { + @include hollow-button; + flex-shrink: 0; + } + + > :nth-last-child(2) { + margin-#{$global-right}: $gap; + } + + > :last-child { + margin-#{$global-left}: auto; + } + + button { + cursor: pointer; + } + } + + .new-link { + @include has-fa-icon(plus-square, solid); + + &::before { + margin-#{$global-right}: $font-icon-margin; + } + } + + > .new-link { + @include regular-button; + } +} diff --git a/app/assets/stylesheets/admin/budgets/show.scss b/app/assets/stylesheets/admin/budgets/show.scss index 1ae4e8413..a35465ce3 100644 --- a/app/assets/stylesheets/admin/budgets/show.scss +++ b/app/assets/stylesheets/admin/budgets/show.scss @@ -9,4 +9,8 @@ } } } + + h4 { + @include header-font-size(h3); + } } diff --git a/app/assets/stylesheets/admin/table_actions.scss b/app/assets/stylesheets/admin/table_actions.scss index 9473c4b36..9fc120522 100644 --- a/app/assets/stylesheets/admin/table_actions.scss +++ b/app/assets/stylesheets/admin/table_actions.scss @@ -5,22 +5,7 @@ a, button { - align-items: center; - display: flex; - flex-direction: column; - font-size: 0.9em; - line-height: $global-lineheight; - text-align: center; - - &:hover, - &:focus { - color: $link-hover; - text-decoration: none; - } - - &::before { - font-size: 1.6em; - } + @include icon-on-top; } button { @@ -114,7 +99,6 @@ @include has-fa-icon(coins, solid); } - .groups-link, .headings-link { @include has-fa-icon(chart-pie, solid); color: $color-success; diff --git a/app/assets/stylesheets/budgets/groups_and_headings.scss b/app/assets/stylesheets/budgets/groups_and_headings.scss index 4871506ed..ba0cd030e 100644 --- a/app/assets/stylesheets/budgets/groups_and_headings.scss +++ b/app/assets/stylesheets/budgets/groups_and_headings.scss @@ -1,4 +1,4 @@ -.groups-and-headings { +.public .groups-and-headings { $spacing: $line-height / 2; .headings-list { diff --git a/app/assets/stylesheets/mixins/icons.scss b/app/assets/stylesheets/mixins/icons.scss index a06306930..80c0982dc 100644 --- a/app/assets/stylesheets/mixins/icons.scss +++ b/app/assets/stylesheets/mixins/icons.scss @@ -1505,3 +1505,22 @@ $font-awesome-icons: ( mask-image: var(--fa-icon-#{$style}-#{$icon}); } } + +@mixin icon-on-top { + align-items: center; + display: flex; + flex-direction: column; + font-size: 0.9em; + line-height: $global-lineheight; + text-align: center; + + &:hover, + &:focus { + color: $link-hover; + text-decoration: none; + } + + &::before { + font-size: 1.6em; + } +} diff --git a/app/components/admin/action_component.rb b/app/components/admin/action_component.rb index debc27c64..77783528c 100644 --- a/app/components/admin/action_component.rb +++ b/app/components/admin/action_component.rb @@ -15,7 +15,13 @@ class Admin::ActionComponent < ApplicationComponent end def text - options[:text] || t("admin.actions.#{action}") + action_key = if action == :destroy + :delete + else + action + end + + options[:text] || t("admin.actions.#{action_key}") end def path diff --git a/app/components/admin/budget_headings/headings_component.html.erb b/app/components/admin/budget_headings/headings_component.html.erb index 9e32dcbe5..4823e58e7 100644 --- a/app/components/admin/budget_headings/headings_component.html.erb +++ b/app/components/admin/budget_headings/headings_component.html.erb @@ -1,8 +1,7 @@ <% if headings.any? %> -

<%= t("admin.budget_headings.amount", count: headings.count) %>

- + <% if budget.approval_voting? %> diff --git a/app/components/admin/budgets/groups_and_headings_component.html.erb b/app/components/admin/budgets/groups_and_headings_component.html.erb new file mode 100644 index 000000000..e9ba73fc9 --- /dev/null +++ b/app/components/admin/budgets/groups_and_headings_component.html.erb @@ -0,0 +1,26 @@ +<% budget.groups.each do |group| %> +
+

<%= group.name %>

+ +
+ <%= action(:edit, group, "aria-label": true) %> + <%= action(:destroy, group, method: :delete, confirm: true, "aria-label": true) %> + <%= action(:new, + group, + text: t("admin.budgets.show.add_heading"), + path: new_admin_budget_group_heading_path(budget, group), + "aria-label": true) %> +
+ + <% if group.multiple_headings? %> +
+
<%= Budget::Group.human_attribute_name(:max_votable_headings) %>
+
<%= group.max_votable_headings %>
+
+ <% end %> + + <%= render Admin::BudgetHeadings::HeadingsComponent.new(group.headings) %> +
+<% end %> + +<%= action(:new, budget, text: t("admin.budgets.show.add_group"), path: new_admin_budget_group_path(budget)) %> diff --git a/app/components/admin/budgets/groups_and_headings_component.rb b/app/components/admin/budgets/groups_and_headings_component.rb new file mode 100644 index 000000000..4b976de9c --- /dev/null +++ b/app/components/admin/budgets/groups_and_headings_component.rb @@ -0,0 +1,13 @@ +class Admin::Budgets::GroupsAndHeadingsComponent < ApplicationComponent + attr_reader :budget + + def initialize(budget) + @budget = budget + end + + private + + def action(...) + render Admin::ActionComponent.new(...) + end +end diff --git a/app/components/admin/budgets/show_component.html.erb b/app/components/admin/budgets/show_component.html.erb index 39cda6458..b5e3e4cda 100644 --- a/app/components/admin/budgets/show_component.html.erb +++ b/app/components/admin/budgets/show_component.html.erb @@ -6,6 +6,11 @@ <%= render Admin::Budgets::DraftingComponent.new(budget) %> <%= render Admin::Budgets::LinksComponent.new(budget) %> +
+

<%= t("admin.budgets.show.groups_and_headings") %>

+ <%= render Admin::Budgets::GroupsAndHeadingsComponent.new(budget) %> +
+

<%= t("admin.budgets.edit.phases_caption") %>

<%= render Admin::BudgetPhases::PhasesComponent.new(budget) %> diff --git a/app/components/admin/budgets/table_actions_component.html.erb b/app/components/admin/budgets/table_actions_component.html.erb index be0abfa07..e17d988a4 100644 --- a/app/components/admin/budgets/table_actions_component.html.erb +++ b/app/components/admin/budgets/table_actions_component.html.erb @@ -2,9 +2,6 @@ <%= actions.action(:investments, text: t("admin.budgets.index.budget_investments"), path: admin_budget_budget_investments_path(budget_id: budget.id)) %> - <%= actions.action(:groups, - text: t("admin.budgets.index.edit_groups"), - path: admin_budget_groups_path(budget)) %> <% if budget.poll.present? %> <%= actions.action(:ballots, text: t("admin.budgets.index.admin_ballots"), diff --git a/app/components/admin/budgets_wizard/phases/index_component.html.erb b/app/components/admin/budgets_wizard/phases/index_component.html.erb index fe5da4590..0a0099d58 100644 --- a/app/components/admin/budgets_wizard/phases/index_component.html.erb +++ b/app/components/admin/budgets_wizard/phases/index_component.html.erb @@ -6,4 +6,4 @@ <%= render Admin::BudgetsWizard::CreationTimelineComponent.new("phases") %> <%= render Admin::BudgetPhases::PhasesComponent.new(budget) %> -<%= link_to t("admin.budgets_wizard.phases.continue"), admin_budgets_path, class: "button success" %> +<%= link_to t("admin.budgets_wizard.phases.continue"), admin_budget_path(budget), class: "button success" %> diff --git a/app/components/admin/table_actions_component.rb b/app/components/admin/table_actions_component.rb index 6df23a8d4..46654e6b8 100644 --- a/app/components/admin/table_actions_component.rb +++ b/app/components/admin/table_actions_component.rb @@ -29,7 +29,7 @@ class Admin::TableActionsComponent < ApplicationComponent end def destroy_text - options[:destroy_text] || t("admin.actions.delete") + options[:destroy_text] end def destroy_path diff --git a/app/controllers/admin/budget_groups_controller.rb b/app/controllers/admin/budget_groups_controller.rb index edbe24f2e..122df99e0 100644 --- a/app/controllers/admin/budget_groups_controller.rb +++ b/app/controllers/admin/budget_groups_controller.rb @@ -1,11 +1,6 @@ class Admin::BudgetGroupsController < Admin::BaseController include Admin::BudgetGroupsActions - before_action :load_groups, only: :index - - def index - end - def new @group = @budget.groups.new end @@ -13,7 +8,7 @@ class Admin::BudgetGroupsController < Admin::BaseController private def groups_index - admin_budget_groups_path(@budget) + admin_budget_path(@budget) end def new_action diff --git a/app/controllers/admin/budget_headings_controller.rb b/app/controllers/admin/budget_headings_controller.rb index 366641a8a..b566b5d74 100644 --- a/app/controllers/admin/budget_headings_controller.rb +++ b/app/controllers/admin/budget_headings_controller.rb @@ -1,9 +1,6 @@ class Admin::BudgetHeadingsController < Admin::BaseController include Admin::BudgetHeadingsActions - def index - end - def new @heading = @group.headings.new end @@ -11,7 +8,7 @@ class Admin::BudgetHeadingsController < Admin::BaseController private def headings_index - admin_budget_group_headings_path(@budget, @group) + admin_budget_path(@budget) end def new_action diff --git a/app/controllers/admin/budgets_wizard/headings_controller.rb b/app/controllers/admin/budgets_wizard/headings_controller.rb index 3b4ee532f..c7ce96668 100644 --- a/app/controllers/admin/budgets_wizard/headings_controller.rb +++ b/app/controllers/admin/budgets_wizard/headings_controller.rb @@ -21,6 +21,10 @@ class Admin::BudgetsWizard::HeadingsController < Admin::BudgetsWizard::BaseContr end end + def load_headings + @headings = @group.headings.order(:id) + end + def new_action :index end diff --git a/app/controllers/concerns/admin/budget_headings_actions.rb b/app/controllers/concerns/admin/budget_headings_actions.rb index 4bc125288..9194404f4 100644 --- a/app/controllers/concerns/admin/budget_headings_actions.rb +++ b/app/controllers/concerns/admin/budget_headings_actions.rb @@ -8,7 +8,6 @@ module Admin::BudgetHeadingsActions before_action :load_budget before_action :load_group - before_action :load_headings, only: :index before_action :load_heading, only: [:edit, :update, :destroy] end @@ -51,10 +50,6 @@ module Admin::BudgetHeadingsActions @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 diff --git a/app/views/admin/budget_groups/_header.html.erb b/app/views/admin/budget_groups/_header.html.erb index 32962bd93..e5b87bdd4 100644 --- a/app/views/admin/budget_groups/_header.html.erb +++ b/app/views/admin/budget_groups/_header.html.erb @@ -1,4 +1,4 @@ -<%= back_link_to admin_budget_groups_path(@budget) %> +<%= back_link_to admin_budget_path(@budget) %>

<%= @budget.name %>

diff --git a/app/views/admin/budget_groups/index.html.erb b/app/views/admin/budget_groups/index.html.erb deleted file mode 100644 index dbddbab42..000000000 --- a/app/views/admin/budget_groups/index.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -<%= back_link_to admin_budgets_path, t("admin.budget_groups.index.back") %> - -
- -
-

<%= @budget.name %>

- <%= link_to t("admin.budget_groups.form.create"), new_admin_budget_group_path %> -
- -<%= render Admin::Budgets::HelpComponent.new("groups") %> -<%= render Admin::BudgetGroups::GroupsComponent.new(@groups) %> diff --git a/app/views/admin/budget_headings/_header.html.erb b/app/views/admin/budget_headings/_header.html.erb index dde0f14ec..d99c6ed9f 100644 --- a/app/views/admin/budget_headings/_header.html.erb +++ b/app/views/admin/budget_headings/_header.html.erb @@ -1,4 +1,4 @@ -<%= back_link_to admin_budget_group_headings_path(@budget, @group) %> +<%= back_link_to admin_budget_path(@budget) %>

<%= "#{@budget.name} / #{@group.name}" %>

diff --git a/app/views/admin/budget_headings/index.html.erb b/app/views/admin/budget_headings/index.html.erb deleted file mode 100644 index fcc2b9886..000000000 --- a/app/views/admin/budget_headings/index.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -<%= back_link_to admin_budget_groups_path(@budget), t("admin.budget_headings.index.back") %> - -
-

<%= t("admin.budget_headings.index.title", budget: @budget.name, group: @group.name) %>

- <%= link_to t("admin.budget_headings.form.create"), new_admin_budget_group_heading_path %> -
- -<%= render Admin::Budgets::HelpComponent.new("headings") %> -<%= render Admin::BudgetHeadings::HeadingsComponent.new(@headings) %> diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 33f391383..ba18332fa 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -90,7 +90,6 @@ en: type_multiple: "Multiple headings" type_pending: "Pending: No headings yet" type_single: "Single heading" - edit_groups: Heading groups admin_ballots: Ballots no_budgets: "There are no budgets." create: @@ -145,6 +144,10 @@ en: multiple: "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." single: "Headings are meant to divide the money of the participatory budget. Since this budget will only contain one heading, this is the place where you stablish the money that will be spent in this participaroty budget." phases: "Participatory budgets have different phases. Here you can enable or disable phases and also customize each individual phase." + show: + add_group: "Add group" + add_heading: "Add heading" + groups_and_headings: "Groups and headings" winners: calculate: Calculate Winner Investments calculated: Winners being calculated, it may take a minute. @@ -170,13 +173,9 @@ en: max_votable_headings_info: "Only applies to the selecting projects phase. During the voting projects phase users can only vote in one heading per group." submit: "Save group" index: - back: "Go back to budgets" new_button: "Add new group" budget_headings: no_headings: "There are no headings." - amount: - one: "There is 1 heading" - other: "There are %{count} headings" create: notice: "Heading created successfully!" update: diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 9d30c4b78..2d17595aa 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -90,7 +90,6 @@ es: type_multiple: "Múltiples partidas" type_pending: "Pendiente: Aún no hay partidas" type_single: "Partida única" - edit_groups: Grupos de partidas admin_ballots: Urnas no_budgets: "No hay presupuestos participativos." create: @@ -145,6 +144,10 @@ es: multiple: "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." single: "Las partidas sirven para dividir el dinero del presupuesto participativo. Como este presupuesto solo tendrá una partida aquí podrás establecer la cantidad de dinero que se gastará en este presupuesto participativo." phases: "Los presupuestos participativos tienen distintas fases. Aquí puedes habilitar o deshabilitar fases y también personalizar cada una de las fases." + show: + add_group: "Añadir grupo" + add_heading: "Añadir partida" + groups_and_headings: "Grupos y partidas" winners: calculate: Calcular proyectos ganadores calculated: Calculando ganadores, puede tardar un minuto. @@ -170,13 +173,9 @@ es: max_votable_headings_info: "Solo se aplica en la fase de apoyos. Durante la votación final un usuario solo puede votar en una partida por grupo." submit: "Guardar grupo" index: - back: "Volver a presupuestos" new_button: "Añadir un grupo nuevo" budget_headings: no_headings: "No hay partidas." - amount: - one: "Hay 1 partida presupuestarias" - other: "Hay %{count} partidas presupuestarias" create: notice: "¡Partida presupuestaria creada con éxito!" update: diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 27776f745..bae512e69 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -57,8 +57,8 @@ namespace :admin do put :calculate_winners end - resources :groups, except: [:show], controller: "budget_groups" do - resources :headings, except: [:show], controller: "budget_headings" + resources :groups, except: [:index, :show], controller: "budget_groups" do + resources :headings, except: [:index, :show], controller: "budget_headings" end resources :budget_investments, only: [:index, :show, :edit, :update] do diff --git a/spec/components/admin/budgets/table_actions_component_spec.rb b/spec/components/admin/budgets/table_actions_component_spec.rb index 86391bff5..ac91530b5 100644 --- a/spec/components/admin/budgets/table_actions_component_spec.rb +++ b/spec/components/admin/budgets/table_actions_component_spec.rb @@ -4,12 +4,11 @@ describe Admin::Budgets::TableActionsComponent, controller: Admin::BaseControlle let(:budget) { create(:budget) } let(:component) { Admin::Budgets::TableActionsComponent.new(budget) } - it "renders actions to edit and delete budget, manage investments and edit groups and manage ballots" do + it "renders actions to edit and delete budget, manage investments and manage ballots" do render_inline component - expect(page).to have_link count: 4 + expect(page).to have_link count: 3 expect(page).to have_link "Investment projects", href: /investments/ - expect(page).to have_link "Heading groups", href: /groups/ expect(page).to have_link "Edit", href: /#{budget.id}\Z/ expect(page).to have_link "Preview", href: /budgets/ diff --git a/spec/controllers/admin/budget_groups_controller_spec.rb b/spec/controllers/admin/budget_groups_controller_spec.rb index 642bd0d08..ca4b480ab 100644 --- a/spec/controllers/admin/budget_groups_controller_spec.rb +++ b/spec/controllers/admin/budget_groups_controller_spec.rb @@ -1,12 +1,12 @@ require "rails_helper" describe Admin::BudgetGroupsController, :admin do - describe "GET index" do + describe "GET new" do it "raises an exception when the feature is disabled" do Setting["process.budgets"] = false expect do - get :index, params: { budget_id: create(:budget).id } + get :new, params: { budget_id: create(:budget).id } end.to raise_exception(FeatureFlags::FeatureDisabled) end end diff --git a/spec/controllers/admin/budget_headings_controller_spec.rb b/spec/controllers/admin/budget_headings_controller_spec.rb index f9f71ffde..5967b44e1 100644 --- a/spec/controllers/admin/budget_headings_controller_spec.rb +++ b/spec/controllers/admin/budget_headings_controller_spec.rb @@ -7,7 +7,7 @@ describe Admin::BudgetHeadingsController, :admin do group = create(:budget_group) expect do - get :index, params: { budget_id: group.budget.id, group_id: group.id } + get :new, params: { budget_id: group.budget.id, group_id: group.id } end.to raise_exception(FeatureFlags::FeatureDisabled) end end diff --git a/spec/system/admin/budget_groups_spec.rb b/spec/system/admin/budget_groups_spec.rb index ac0010afa..a817a148c 100644 --- a/spec/system/admin/budget_groups_spec.rb +++ b/spec/system/admin/budget_groups_spec.rb @@ -14,96 +14,75 @@ describe "Admin budget groups", :admin do end end - context "Index" do + context "List of groups from budget page" do scenario "Displaying no groups for budget" do - visit admin_budget_groups_path(budget) + visit admin_budget_path(budget) - expect(page).to have_content "There are no groups." + within "section", text: "Groups and headings" do + expect(page.text).to eq "Groups and headings\nAdd group" + end end scenario "Displaying groups" do - group1 = create(:budget_group, budget: budget) + above = create(:budget_group, budget: budget, name: "Above ground") + below = create(:budget_group, budget: budget, name: "Below ground") - group2 = create(:budget_group, budget: budget) - create(:budget_heading, group: group2) + 1.times { create(:budget_heading, group: above) } + 2.times { create(:budget_heading, group: below) } - group3 = create(:budget_group, budget: budget, max_votable_headings: 2) - 3.times { create(:budget_heading, group: group3) } - visit admin_budget_groups_path(budget) - expect(page).to have_content "There are 3 groups" + visit admin_budget_path(budget) - within "#budget_group_#{group1.id}" do - expect(page).to have_content(group1.name) - expect(page).to have_content(group1.max_votable_headings) - expect(page).to have_content(group1.headings.count) - expect(page).to have_link "Headings" - end + within "section", text: "Groups and headings" do + within "section", text: "Above ground" do + expect(page).to have_css "h4", exact_text: "Above ground" + expect(page).not_to have_content "Maximum number of headings" + end - within "#budget_group_#{group2.id}" do - expect(page).to have_content(group2.name) - expect(page).to have_content(group2.max_votable_headings) - expect(page).to have_content(group2.headings.count) - expect(page).to have_link "Headings" - end - - within "#budget_group_#{group3.id}" do - expect(page).to have_content(group3.name) - expect(page).to have_content(group3.max_votable_headings) - expect(page).to have_content(group3.headings.count) - expect(page).to have_link "Headings" + within "section", text: "Below ground" do + expect(page).to have_css "h4", exact_text: "Below ground" + expect(page).to have_content "Maximum number of headings in which a user can select projects 1" + end end end scenario "Delete a group without headings" do - group = create(:budget_group, budget: budget) + create(:budget_group, budget: budget, name: "Nowhere") - visit admin_budget_groups_path(budget) - within("#budget_group_#{group.id}") { accept_confirm { click_button "Delete" } } + visit admin_budget_path(budget) + + accept_confirm { click_button "Delete Nowhere" } expect(page).to have_content "Group deleted successfully" - expect(page).not_to have_selector "#budget_group_#{group.id}" + expect(page).not_to have_content "Nowhere" end scenario "Try to delete a group with headings" do - group = create(:budget_group, budget: budget) - create(:budget_heading, group: group) + group = create(:budget_group, budget: budget, name: "Everywhere") + create(:budget_heading, group: group, name: "Everything") - visit admin_budget_groups_path(budget) - within("#budget_group_#{group.id}") { accept_confirm { click_button "Delete" } } + visit admin_budget_path(budget) + + accept_confirm { click_button "Delete Everywhere" } expect(page).to have_content "You cannot delete a Group that has associated headings" - expect(page).to have_selector "#budget_group_#{group.id}" + expect(page).to have_content "Everywhere" end end context "New" do scenario "Create group" do - visit admin_budget_groups_path(budget) - click_link "Create new group" + visit admin_budget_path(budget) + click_link "Add group" fill_in "Group name", with: "All City" click_button "Create new group" expect(page).to have_content "Group created successfully!" - expect(page).to have_content "All City" - end - scenario "Maximum number of headings in which a user can vote is set to 1 by default" do - visit new_admin_budget_group_path(budget) - fill_in "Group name", with: "All City" - - click_button "Create new group" - - expect(page).to have_content "Group created successfully!" - - within all("thead th")[1] do - expect(page).to have_content("Maximum number of headings in which a user can select projects") - end - - within "tbody tr" do - within all("td")[1] { expect(page.text).to eq "1" } + within "section", text: "Groups and headings" do + expect(page).to have_css "h4", exact_text: "All City" end end @@ -119,13 +98,14 @@ describe "Admin budget groups", :admin do context "Edit" do scenario "Show group information" do - group = create(:budget_group, budget: budget, max_votable_headings: 2) + group = create(:budget_group, budget: budget, name: "Everywhere", max_votable_headings: 2) 2.times { create(:budget_heading, group: group) } - visit admin_budget_groups_path(budget) - within("#budget_group_#{group.id}") { click_link "Edit" } + visit admin_budget_path(budget) - expect(page).to have_field "Group name", with: group.name + click_link "Edit Everywhere" + + expect(page).to have_field "Group name", with: "Everywhere" expect(page).to have_field "Maximum number of headings in which a user can select projects", with: "2" end diff --git a/spec/system/admin/budget_headings_spec.rb b/spec/system/admin/budget_headings_spec.rb index d6a90229e..59ae87b30 100644 --- a/spec/system/admin/budget_headings_spec.rb +++ b/spec/system/admin/budget_headings_spec.rb @@ -2,7 +2,7 @@ require "rails_helper" describe "Admin budget headings", :admin do let(:budget) { create(:budget, :drafting) } - let(:group) { create(:budget_group, budget: budget) } + let!(:group) { create(:budget_group, budget: budget) } context "Load" do let!(:budget) { create(:budget, slug: "budget_slug") } @@ -17,64 +17,63 @@ describe "Admin budget headings", :admin do end end - context "Index" do + context "List of headings in the budget page" do scenario "Displaying no headings for group" do - visit admin_budget_group_headings_path(budget, group) + visit admin_budget_path(budget) - expect(page).to have_content "There are no headings." + within "section", text: "Groups and headings" do + expect(page).to have_content "There are no headings." + end end scenario "Displaying headings" do - heading1 = create(:budget_heading, group: group, price: 1000, allow_custom_content: true) - heading2 = create(:budget_heading, group: group, price: 2000, population: 10000) - heading3 = create(:budget_heading, group: group, price: 3000, population: 10000) + create(:budget_heading, name: "Laptops", group: group, price: 1000, allow_custom_content: true) + create(:budget_heading, name: "Tablets", group: group, price: 2000, population: 10000) + create(:budget_heading, name: "Phones", group: group, price: 3000, population: 20000) - visit admin_budget_group_headings_path(budget, group) - expect(page).to have_content "There are 3 headings" + visit admin_budget_path(budget) - within "#budget_heading_#{heading1.id}" do - expect(page).to have_content(heading1.name) - expect(page).to have_content "€1,000" - expect(page).not_to have_content "10000" - expect(page).to have_content "Yes" - expect(page).to have_link "Edit" - expect(page).to have_button "Delete" - end + within "section", text: "Groups and headings" do + within "tbody" do + expect(page).to have_selector "tr", count: 3 - within "#budget_heading_#{heading2.id}" do - expect(page).to have_content(heading2.name) - expect(page).to have_content "€2,000" - expect(page).to have_content "10000" - expect(page).to have_content "No" - expect(page).to have_link "Edit" - expect(page).to have_button "Delete" - end + within "tr", text: "Laptops" do + expect(page).to have_content "€1,000" + expect(page).not_to have_content "10000" + expect(page).to have_content "Yes" + end - within "#budget_heading_#{heading3.id}" do - expect(page).to have_content(heading3.name) - expect(page).to have_content "€3,000" - expect(page).to have_content "10000" - expect(page).to have_content "No" - expect(page).to have_link "Edit" - expect(page).to have_button "Delete" + within "tr", text: "Tablets" do + expect(page).to have_content "€2,000" + expect(page).to have_content "10000" + expect(page).to have_content "No" + end + + within "tr", text: "Phones" do + expect(page).to have_content "€3,000" + expect(page).to have_content "20000" + expect(page).to have_content "No" + end + end end end scenario "Delete a heading without investments" do - heading = create(:budget_heading, group: group) + create(:budget_heading, group: group, name: "Lemuria") - visit admin_budget_group_headings_path(budget, group) - within("#budget_heading_#{heading.id}") { accept_confirm { click_button "Delete" } } + visit admin_budget_path(budget) + + within("tr", text: "Lemuria") { accept_confirm { click_button "Delete" } } expect(page).to have_content "Heading deleted successfully" - expect(page).not_to have_selector "#budget_heading_#{heading.id}" + expect(page).not_to have_content "Lemuria" end scenario "Try to delete a heading with investments" do heading = create(:budget_heading, group: group, name: "Atlantis") create(:budget_investment, heading: heading) - visit admin_budget_group_headings_path(budget, group) + visit admin_budget_path(budget) within(".heading", text: "Atlantis") { accept_confirm { click_button "Delete" } } expect(page).to have_content "You cannot delete a Heading that has associated investments" @@ -84,8 +83,11 @@ describe "Admin budget headings", :admin do context "New" do scenario "Create heading" do - visit admin_budget_group_headings_path(budget, group) - click_link "Create new heading" + visit admin_budget_path(budget) + + within "section", text: "Groups and headings" do + within("section", text: group.name) { click_link "Add heading" } + end fill_in "Heading name", with: "All City" fill_in "Money amount", with: "1000" @@ -95,10 +97,12 @@ describe "Admin budget headings", :admin do click_button "Create new heading" expect(page).to have_content "Heading created successfully!" - expect(page).to have_content "All City" - expect(page).to have_content "€1,000" - expect(page).to have_content "10000" - expect(page).to have_content "Yes" + + within "tr", text: "All City" do + expect(page).to have_content "€1,000" + expect(page).to have_content "10000" + expect(page).to have_content "Yes" + end end scenario "Heading name is mandatory" do @@ -148,7 +152,7 @@ describe "Admin budget headings", :admin do scenario "Show heading information" do heading = create(:budget_heading, group: group) - visit admin_budget_group_headings_path(budget, group) + visit admin_budget_path(budget) within("#budget_heading_#{heading.id}") { click_link "Edit" } expect(page).to have_field "Heading name", with: heading.name diff --git a/spec/system/admin/budgets_wizard/groups_spec.rb b/spec/system/admin/budgets_wizard/groups_spec.rb index ec8ae5cd6..71e170b16 100644 --- a/spec/system/admin/budgets_wizard/groups_spec.rb +++ b/spec/system/admin/budgets_wizard/groups_spec.rb @@ -112,10 +112,11 @@ describe "Budgets wizard, groups step", :admin do expect(page).to have_content "Group updated successfully" - visit admin_budget_groups_path(budget) + visit admin_budget_path(budget) - expect(page).to have_content "There is 1 group" - within("tbody tr") { expect(page).to have_content "Group without typos" } + within "section", text: "Groups and headings" do + expect(page).to have_css "h4", exact_text: "Group without typos" + end end end diff --git a/spec/system/admin/budgets_wizard/headings_spec.rb b/spec/system/admin/budgets_wizard/headings_spec.rb index ef651ab04..986703434 100644 --- a/spec/system/admin/budgets_wizard/headings_spec.rb +++ b/spec/system/admin/budgets_wizard/headings_spec.rb @@ -136,10 +136,11 @@ describe "Budgets wizard, headings step", :admin do expect(page).to have_content "Heading updated successfully" - visit admin_budget_group_headings_path(budget, group) + visit admin_budget_path(budget) - expect(page).to have_content "There is 1 heading" - within("tbody tr") { expect(page).to have_content "Heading without typos" } + within "section", text: "Groups and headings" do + within("tbody tr") { expect(page).to have_content "Heading without typos" } + end end end diff --git a/spec/system/admin/budgets_wizard/phases_spec.rb b/spec/system/admin/budgets_wizard/phases_spec.rb index 2f053689d..c5a19fa5a 100644 --- a/spec/system/admin/budgets_wizard/phases_spec.rb +++ b/spec/system/admin/budgets_wizard/phases_spec.rb @@ -43,7 +43,7 @@ describe "Budgets wizard, phases step", :admin do click_link "Finish" - within("tr", text: budget.name) { click_link "Edit" } + expect(page).to have_css "section h3", exact_text: "Phases" within "tr", text: "Information" do expect(page).to have_content "No" diff --git a/spec/system/admin/budgets_wizard/wizard_spec.rb b/spec/system/admin/budgets_wizard/wizard_spec.rb index e2495aef4..97fcd3d51 100644 --- a/spec/system/admin/budgets_wizard/wizard_spec.rb +++ b/spec/system/admin/budgets_wizard/wizard_spec.rb @@ -24,20 +24,12 @@ describe "Budgets creation wizard", :admin do click_link "Finish" - within "tr", text: "Single heading budget" do - click_link "Heading groups" - end + within "section", text: "Groups and headings" do + expect(page).to have_content "Single heading budget" - expect(page).to have_content "There is 1 group" - - within "tr", text: "Single heading budget" do - click_link "Headings" - end - - expect(page).to have_content "There is 1 heading" - - within "tbody" do - expect(page).to have_content "One and only heading" + within "tbody" do + expect(page).to have_content "One and only heading" + end end end @@ -119,26 +111,21 @@ describe "Budgets creation wizard", :admin do click_link "Finish" - within "tr", text: "Multiple headings budget" do - click_link "Heading groups" - end + within "section", text: "Groups and headings" do + within "section", text: "All city" do + within "tbody" do + expect(page).to have_css "tr", count: 1 + expect(page).to have_content "All city" + end + end - expect(page).to have_content "There are 2 groups" - - within "tbody" do - expect(page).to have_content "All city" - expect(page).to have_content "Districts" - end - - within "tr", text: "Districts" do - click_link "Headings" - end - - expect(page).to have_content "There are 2 headings" - - within "tbody" do - expect(page).to have_content "North" - expect(page).to have_content "South" + within "section", text: "Districts" do + within "tbody" do + expect(page).to have_css "tr", count: 2 + expect(page).to have_content "North" + expect(page).to have_content "South" + end + end end end end
<%= Budget::Heading.human_attribute_name(:name) %> <%= Budget::Heading.human_attribute_name(:price) %>