Groups and headings CRUD from budget view
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 <javim@elretirao.net>
This commit is contained in:
committed by
Javi Martín
parent
c8827f5c7f
commit
2b709f1a36
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
@include header-font-size(h3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.groups-and-headings {
|
||||
.public .groups-and-headings {
|
||||
$spacing: $line-height / 2;
|
||||
|
||||
.headings-list {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<% if headings.any? %>
|
||||
<h3><%= t("admin.budget_headings.amount", count: headings.count) %></h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr id="<%= dom_id(group) %>">
|
||||
<tr>
|
||||
<th><%= Budget::Heading.human_attribute_name(:name) %></th>
|
||||
<th><%= Budget::Heading.human_attribute_name(:price) %></th>
|
||||
<% if budget.approval_voting? %>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<% budget.groups.each do |group| %>
|
||||
<section id="<%= dom_id(group) %>" aria-labelledby="<%= dom_id(group, :header) %>">
|
||||
<h4 id="<%= dom_id(group, :header) %>"><%= group.name %></h4>
|
||||
|
||||
<div class="groups-actions">
|
||||
<%= 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) %>
|
||||
</div>
|
||||
|
||||
<% if group.multiple_headings? %>
|
||||
<dl>
|
||||
<dt><%= Budget::Group.human_attribute_name(:max_votable_headings) %></dt>
|
||||
<dd><%= group.max_votable_headings %></dd>
|
||||
</dl>
|
||||
<% end %>
|
||||
|
||||
<%= render Admin::BudgetHeadings::HeadingsComponent.new(group.headings) %>
|
||||
</section>
|
||||
<% end %>
|
||||
|
||||
<%= action(:new, budget, text: t("admin.budgets.show.add_group"), path: new_admin_budget_group_path(budget)) %>
|
||||
@@ -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
|
||||
@@ -6,6 +6,11 @@
|
||||
<%= render Admin::Budgets::DraftingComponent.new(budget) %>
|
||||
<%= render Admin::Budgets::LinksComponent.new(budget) %>
|
||||
|
||||
<section class="groups-and-headings" aria-labelledby="groups_and_headings_header">
|
||||
<h3 id="groups_and_headings_header"><%= t("admin.budgets.show.groups_and_headings") %></h3>
|
||||
<%= render Admin::Budgets::GroupsAndHeadingsComponent.new(budget) %>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="phases_header">
|
||||
<h3 id="phases_header"><%= t("admin.budgets.edit.phases_caption") %></h3>
|
||||
<%= render Admin::BudgetPhases::PhasesComponent.new(budget) %>
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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" %>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%= back_link_to admin_budget_groups_path(@budget) %>
|
||||
<%= back_link_to admin_budget_path(@budget) %>
|
||||
|
||||
<h2><%= @budget.name %></h2>
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<%= back_link_to admin_budgets_path, t("admin.budget_groups.index.back") %>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<header>
|
||||
<h2><%= @budget.name %></h2>
|
||||
<%= link_to t("admin.budget_groups.form.create"), new_admin_budget_group_path %>
|
||||
</header>
|
||||
|
||||
<%= render Admin::Budgets::HelpComponent.new("groups") %>
|
||||
<%= render Admin::BudgetGroups::GroupsComponent.new(@groups) %>
|
||||
@@ -1,4 +1,4 @@
|
||||
<%= back_link_to admin_budget_group_headings_path(@budget, @group) %>
|
||||
<%= back_link_to admin_budget_path(@budget) %>
|
||||
|
||||
<h2><%= "#{@budget.name} / #{@group.name}" %></h2>
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<%= back_link_to admin_budget_groups_path(@budget), t("admin.budget_headings.index.back") %>
|
||||
|
||||
<header>
|
||||
<h2><%= t("admin.budget_headings.index.title", budget: @budget.name, group: @group.name) %></h2>
|
||||
<%= link_to t("admin.budget_headings.form.create"), new_admin_budget_group_heading_path %>
|
||||
</header>
|
||||
|
||||
<%= render Admin::Budgets::HelpComponent.new("headings") %>
|
||||
<%= render Admin::BudgetHeadings::HeadingsComponent.new(@headings) %>
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
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"
|
||||
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
|
||||
|
||||
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"
|
||||
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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
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)
|
||||
within "section", text: "Groups and headings" do
|
||||
within "tbody" do
|
||||
expect(page).to have_selector "tr", count: 3
|
||||
|
||||
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"
|
||||
expect(page).to have_link "Edit"
|
||||
expect(page).to have_button "Delete"
|
||||
end
|
||||
|
||||
within "#budget_heading_#{heading2.id}" do
|
||||
expect(page).to have_content(heading2.name)
|
||||
within "tr", text: "Tablets" do
|
||||
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 "#budget_heading_#{heading3.id}" do
|
||||
expect(page).to have_content(heading3.name)
|
||||
within "tr", text: "Phones" do
|
||||
expect(page).to have_content "€3,000"
|
||||
expect(page).to have_content "10000"
|
||||
expect(page).to have_content "20000"
|
||||
expect(page).to have_content "No"
|
||||
expect(page).to have_link "Edit"
|
||||
expect(page).to have_button "Delete"
|
||||
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,11 +97,13 @@ 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"
|
||||
|
||||
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
|
||||
visit new_admin_budget_group_heading_path(budget, group)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -136,12 +136,13 @@ 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 "section", text: "Groups and headings" do
|
||||
within("tbody tr") { expect(page).to have_content "Heading without typos" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Destroy" do
|
||||
scenario "delete a heading without investments" do
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -24,22 +24,14 @@ describe "Budgets creation wizard", :admin do
|
||||
|
||||
click_link "Finish"
|
||||
|
||||
within "tr", text: "Single heading budget" do
|
||||
click_link "Heading groups"
|
||||
end
|
||||
|
||||
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 "section", text: "Groups and headings" do
|
||||
expect(page).to have_content "Single heading budget"
|
||||
|
||||
within "tbody" do
|
||||
expect(page).to have_content "One and only heading"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Creation of a multiple-headings budget by steps" do
|
||||
visit admin_budgets_path
|
||||
@@ -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
|
||||
|
||||
expect(page).to have_content "There are 2 groups"
|
||||
|
||||
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"
|
||||
expect(page).to have_content "Districts"
|
||||
end
|
||||
end
|
||||
|
||||
within "tr", text: "Districts" do
|
||||
click_link "Headings"
|
||||
end
|
||||
|
||||
expect(page).to have_content "There are 2 headings"
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user