change CRUD for budget groups and headings
To make it more consistent with the rest of the Admin panel, the CRUD for budget groups and headings has been changed from the old "all-in-one" form to a separate form for each resource.
This commit is contained in:
@@ -2,20 +2,60 @@ class Admin::BudgetGroupsController < Admin::BaseController
|
|||||||
include FeatureFlags
|
include FeatureFlags
|
||||||
feature_flag :budgets
|
feature_flag :budgets
|
||||||
|
|
||||||
|
before_action :load_budget
|
||||||
|
before_action :load_group, except: [:index, :new, :create]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@groups = @budget.groups.order(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@group = @budget.groups.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@budget = Budget.find(params[:budget_id])
|
@group = @budget.groups.new(budget_group_params)
|
||||||
@budget.groups.create(budget_group_params)
|
if @group.save
|
||||||
@groups = @budget.groups.includes(:headings)
|
redirect_to groups_index, notice: t("admin.budget_groups.create.notice")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@budget = Budget.find(params[:budget_id])
|
if @group.update(budget_group_params)
|
||||||
@group = @budget.groups.find(params[:id])
|
redirect_to groups_index, notice: t("admin.budget_groups.update.notice")
|
||||||
@group.update(budget_group_params)
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @group.headings.any?
|
||||||
|
redirect_to groups_index, alert: t("admin.budget_groups.destroy.unable_notice")
|
||||||
|
else
|
||||||
|
@group.destroy
|
||||||
|
redirect_to groups_index, notice: t("admin.budget_groups.destroy.success_notice")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def load_budget
|
||||||
|
@budget = Budget.includes(:groups).find(params[:budget_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_group
|
||||||
|
@group = @budget.groups.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def groups_index
|
||||||
|
admin_budget_groups_path(@budget)
|
||||||
|
end
|
||||||
|
|
||||||
def budget_group_params
|
def budget_group_params
|
||||||
params.require(:budget_group).permit(:name, :max_votable_headings)
|
params.require(:budget_group).permit(:name, :max_votable_headings)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -2,36 +2,65 @@ class Admin::BudgetHeadingsController < Admin::BaseController
|
|||||||
include FeatureFlags
|
include FeatureFlags
|
||||||
feature_flag :budgets
|
feature_flag :budgets
|
||||||
|
|
||||||
def create
|
before_action :load_budget
|
||||||
@budget = Budget.find(params[:budget_id])
|
before_action :load_group
|
||||||
@budget_group = @budget.groups.find(params[:budget_group_id])
|
before_action :load_heading, except: [:index, :new, :create]
|
||||||
@budget_group.headings.create(budget_heading_params)
|
|
||||||
@headings = @budget_group.headings
|
def index
|
||||||
|
@headings = @group.headings.order(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@heading = @group.headings.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@budget = Budget.find(params[:budget_id])
|
end
|
||||||
@budget_group = @budget.groups.find(params[:budget_group_id])
|
|
||||||
@heading = Budget::Heading.find(params[:id])
|
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
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@budget = Budget.find(params[:budget_id])
|
if @heading.update(budget_heading_params)
|
||||||
@budget_group = @budget.groups.find(params[:budget_group_id])
|
redirect_to headings_index, notice: t('admin.budget_headings.update.notice')
|
||||||
@heading = Budget::Heading.find(params[:id])
|
else
|
||||||
@heading.assign_attributes(budget_heading_params)
|
render :edit
|
||||||
render :edit unless @heading.save
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@heading = Budget::Heading.find(params[:id])
|
if @heading.can_be_deleted?
|
||||||
@heading.destroy
|
@heading.destroy
|
||||||
@budget = Budget.find(params[:budget_id])
|
redirect_to headings_index, notice: t('admin.budget_headings.destroy.success_notice')
|
||||||
redirect_to admin_budget_path(@budget)
|
else
|
||||||
|
redirect_to headings_index, alert: t('admin.budget_headings.destroy.unable_notice')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def load_budget
|
||||||
|
@budget = Budget.includes(:groups).find(params[:budget_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_group
|
||||||
|
@group = @budget.groups.find(params[:group_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_heading
|
||||||
|
@heading = @group.headings.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def headings_index
|
||||||
|
admin_budget_group_headings_path(@budget, @group)
|
||||||
|
end
|
||||||
|
|
||||||
def budget_heading_params
|
def budget_heading_params
|
||||||
params.require(:budget_heading).permit(:name, :price, :population, :allow_custom_content, :latitude, :longitude)
|
params.require(:budget_heading).permit(:name, :price, :population, :allow_custom_content, :latitude, :longitude)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ class Admin::BudgetsController < Admin::BaseController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@budget = Budget.includes(groups: :headings).find(params[:id])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def new; end
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
def edit; end
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
def calculate_winners
|
def calculate_winners
|
||||||
return unless @budget.balloting_process?
|
return unless @budget.balloting_process?
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ module Budgets
|
|||||||
def create
|
def create
|
||||||
load_investment
|
load_investment
|
||||||
load_heading
|
load_heading
|
||||||
|
load_map
|
||||||
|
|
||||||
@ballot.add_investment(@investment)
|
@ballot.add_investment(@investment)
|
||||||
end
|
end
|
||||||
@@ -24,6 +25,7 @@ module Budgets
|
|||||||
def destroy
|
def destroy
|
||||||
@investment = @line.investment
|
@investment = @line.investment
|
||||||
load_heading
|
load_heading
|
||||||
|
load_map
|
||||||
|
|
||||||
@line.destroy
|
@line.destroy
|
||||||
load_investments
|
load_investments
|
||||||
@@ -74,6 +76,12 @@ module Budgets
|
|||||||
@ballot_referer = session[:ballot_referer]
|
@ballot_referer = session[:ballot_referer]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_map
|
||||||
|
@investments ||= []
|
||||||
|
@investments_map_coordinates = MapLocation.where(investment: @investments).map(&:json_data)
|
||||||
|
@map_location = MapLocation.load_from_heading(@heading)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
18
app/views/admin/budget_groups/_form.html.erb
Normal file
18
app/views/admin/budget_groups/_form.html.erb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<div class="small-12 medium-6">
|
||||||
|
<%= form_for [:admin, @budget, @group], url: path do |f| %>
|
||||||
|
|
||||||
|
<%= f.text_field :name,
|
||||||
|
label: t("admin.budget_groups.form.name"),
|
||||||
|
maxlength: 50,
|
||||||
|
placeholder: t("admin.budget_groups.form.name") %>
|
||||||
|
|
||||||
|
<% if @group.persisted? %>
|
||||||
|
<%= f.select :max_votable_headings,
|
||||||
|
(1..@group.headings.count),
|
||||||
|
label: t("admin.budget_groups.max_votable_headings"),
|
||||||
|
placeholder: t("admin.budget_groups.max_votable_headings") %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= f.submit t("admin.budget_groups.form.#{action}"), class: "button success" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
5
app/views/admin/budget_groups/_header.html.erb
Normal file
5
app/views/admin/budget_groups/_header.html.erb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<%= back_link_to admin_budget_groups_path(@budget) %>
|
||||||
|
|
||||||
|
<h2><%= @budget.name %></h2>
|
||||||
|
|
||||||
|
<h3><%= t("admin.budget_groups.form.#{action}") %></h3>
|
||||||
3
app/views/admin/budget_groups/edit.html.erb
Normal file
3
app/views/admin/budget_groups/edit.html.erb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<%= render "header", action: "edit" %>
|
||||||
|
|
||||||
|
<%= render "form", path: admin_budget_group_path(@budget, @group), action: "edit" %>
|
||||||
44
app/views/admin/budget_groups/index.html.erb
Normal file
44
app/views/admin/budget_groups/index.html.erb
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<h2 class="inline-block"><%= @budget.name %></h2>
|
||||||
|
|
||||||
|
<%= link_to t("admin.budget_groups.form.create"),
|
||||||
|
new_admin_budget_group_path,
|
||||||
|
class: "button float-right" %>
|
||||||
|
|
||||||
|
<% if @groups.any? %>
|
||||||
|
<h3><%= t("admin.budget_groups.amount", count: @groups.count) %></h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr id="<%= dom_id(@budget) %>">
|
||||||
|
<th><%= t("admin.budget_groups.name") %></th>
|
||||||
|
<th><%= t("admin.budget_groups.max_votable_headings") %></th>
|
||||||
|
<th><%= t("admin.budget_groups.headings_name") %></th>
|
||||||
|
<th><%= t("admin.budget_groups.headings_edit") %></th>
|
||||||
|
<th><%= t("admin.actions.actions") %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @groups.each do |group| %>
|
||||||
|
<tr id="<%= dom_id(group) %>">
|
||||||
|
<td><%= link_to group.name, edit_admin_budget_group_path(@budget, group) %></td>
|
||||||
|
<td><%= group.max_votable_headings %></td>
|
||||||
|
<td><%= group.headings.count %></td>
|
||||||
|
<td><%= link_to t("admin.budget_groups.headings_manage"),
|
||||||
|
admin_budget_group_headings_path(@budget, group) %></td>
|
||||||
|
<td>
|
||||||
|
<%= link_to t("admin.actions.edit"),
|
||||||
|
edit_admin_budget_group_path(@budget, group),
|
||||||
|
class: "button hollow" %>
|
||||||
|
<%= link_to t("admin.actions.delete"),
|
||||||
|
admin_budget_group_path(@budget, group),
|
||||||
|
method: :delete,
|
||||||
|
class: "button hollow alert" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<div class="callout primary clear">
|
||||||
|
<%= t("admin.budget_groups.no_groups") %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
3
app/views/admin/budget_groups/new.html.erb
Normal file
3
app/views/admin/budget_groups/new.html.erb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<%= render "header", action: "create" %>
|
||||||
|
|
||||||
|
<%= render "form", path: admin_budget_groups_path(@budget), action: "create" %>
|
||||||
40
app/views/admin/budget_headings/_form.html.erb
Normal file
40
app/views/admin/budget_headings/_form.html.erb
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<div class="small-12 medium-6">
|
||||||
|
|
||||||
|
<%= form_for [:admin, @budget, @group, @heading], url: path do |f| %>
|
||||||
|
|
||||||
|
<%= f.text_field :name,
|
||||||
|
label: t("admin.budget_headings.form.name"),
|
||||||
|
maxlength: 50,
|
||||||
|
placeholder: t("admin.budget_headings.form.name") %>
|
||||||
|
|
||||||
|
<%= f.text_field :price,
|
||||||
|
label: t("admin.budget_headings.form.amount"),
|
||||||
|
maxlength: 8,
|
||||||
|
placeholder: t("admin.budget_headings.form.amount") %>
|
||||||
|
|
||||||
|
<%= f.label :population, t("admin.budget_headings.form.population") %>
|
||||||
|
<p class="help-text" id="budgets-population-help-text">
|
||||||
|
<%= t("admin.budget_headings.form.population_info") %>
|
||||||
|
</p>
|
||||||
|
<%= f.text_field :population,
|
||||||
|
label: false,
|
||||||
|
maxlength: 8,
|
||||||
|
placeholder: t("admin.budget_headings.form.population"),
|
||||||
|
data: {toggle_focus: "population-info"},
|
||||||
|
aria: {describedby: "budgets-population-help-text"} %>
|
||||||
|
|
||||||
|
<%= f.text_field :latitude,
|
||||||
|
label: t("admin.budget_headings.form.latitude"),
|
||||||
|
maxlength: 22,
|
||||||
|
placeholder: "latitude" %>
|
||||||
|
|
||||||
|
<%= f.text_field :longitude,
|
||||||
|
label: t("admin.budget_headings.form.longitude"),
|
||||||
|
maxlength: 22,
|
||||||
|
placeholder: "longitude" %>
|
||||||
|
|
||||||
|
<%= f.check_box :allow_custom_content, label: t("admin.budget_headings.form.allow_content_block") %>
|
||||||
|
|
||||||
|
<%= f.submit t("admin.budget_headings.form.#{action}"), class: "button success" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
5
app/views/admin/budget_headings/_header.html.erb
Normal file
5
app/views/admin/budget_headings/_header.html.erb
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<%= back_link_to admin_budget_group_headings_path(@budget, @group) %>
|
||||||
|
|
||||||
|
<h2><%= "#{@budget.name} / #{@group.name}" %></h2>
|
||||||
|
|
||||||
|
<h3><%= t("admin.budget_headings.form.#{action}") %></h3>
|
||||||
3
app/views/admin/budget_headings/edit.html.erb
Normal file
3
app/views/admin/budget_headings/edit.html.erb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<%= render "header", action: "edit" %>
|
||||||
|
|
||||||
|
<%= render "form", path: admin_budget_group_heading_path(@budget, @group, @heading), action: "edit" %>
|
||||||
47
app/views/admin/budget_headings/index.html.erb
Normal file
47
app/views/admin/budget_headings/index.html.erb
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<%= back_link_to admin_budget_groups_path(@budget) %>
|
||||||
|
|
||||||
|
<div class="clear"></div>
|
||||||
|
<h2 class="inline-block"><%= "#{@budget.name} / #{@group.name}" %></h2>
|
||||||
|
<%= link_to t("admin.budget_headings.form.create"),
|
||||||
|
new_admin_budget_group_heading_path,
|
||||||
|
class: "button float-right" %>
|
||||||
|
|
||||||
|
<% if @headings.any? %>
|
||||||
|
<h3><%= t("admin.budget_headings.amount", count: @headings.count) %></h3>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr id="<%= dom_id(@group) %>">
|
||||||
|
<th><%= t("admin.budget_headings.name") %></th>
|
||||||
|
<th><%= t("admin.budget_headings.form.amount") %></th>
|
||||||
|
<th><%= t("admin.budget_headings.form.population") %></th>
|
||||||
|
<th><%= t("admin.budget_headings.form.allow_content_block") %></th>
|
||||||
|
<th><%= t("admin.actions.actions") %></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% @headings.each do |heading| %>
|
||||||
|
<tr id="<%= dom_id(heading) %>">
|
||||||
|
<td><%= link_to heading.name, edit_admin_budget_group_heading_path(@budget, @group, heading) %></td>
|
||||||
|
<td><%= @budget.formatted_heading_price(heading) %></td>
|
||||||
|
<td><%= heading.population %></td>
|
||||||
|
<td>
|
||||||
|
<%= heading.allow_custom_content ? t("admin.shared.true_value") : t("admin.shared.false_value") %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= link_to t("admin.actions.edit"),
|
||||||
|
edit_admin_budget_group_heading_path(@budget, @group, heading),
|
||||||
|
class: "button hollow" %>
|
||||||
|
<%= link_to t("admin.actions.delete"),
|
||||||
|
admin_budget_group_heading_path(@budget, @group, heading),
|
||||||
|
method: :delete,
|
||||||
|
class: "button hollow alert" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<div class="callout primary clear">
|
||||||
|
<%= t("admin.budget_headings.no_headings") %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
3
app/views/admin/budget_headings/new.html.erb
Normal file
3
app/views/admin/budget_headings/new.html.erb
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<%= render "header", action: "create" %>
|
||||||
|
|
||||||
|
<%= render "form", path: admin_budget_group_headings_path(@budget, @group), action: "create" %>
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<% @budgets.each do |budget| %>
|
<% @budgets.each do |budget| %>
|
||||||
<tr id="<%= dom_id(budget) %>" class="budget">
|
<tr id="<%= dom_id(budget) %>" class="budget">
|
||||||
<td>
|
<td>
|
||||||
<%= budget.name %>
|
<%= link_to budget.name, admin_budget_path(budget) %>
|
||||||
</td>
|
</td>
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<%= t("budgets.phase.#{budget.phase}") %>
|
<%= t("budgets.phase.#{budget.phase}") %>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
class: "button hollow medium" %>
|
class: "button hollow medium" %>
|
||||||
</td>
|
</td>
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<%= link_to t("admin.budgets.index.edit_groups"), admin_budget_path(budget) %>
|
<%= link_to t("admin.budgets.index.edit_groups"), admin_budget_groups_path(budget) %>
|
||||||
</td>
|
</td>
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<%= link_to t("admin.budgets.index.edit_budget"), edit_admin_budget_path(budget) %>
|
<%= link_to t("admin.budgets.index.edit_budget"), edit_admin_budget_path(budget) %>
|
||||||
|
|||||||
@@ -2,6 +2,4 @@
|
|||||||
|
|
||||||
<h2><%= @budget.name %></h2>
|
<h2><%= @budget.name %></h2>
|
||||||
|
|
||||||
<div id="<%= dom_id @budget %>_groups">
|
<%= render "form" %>
|
||||||
<%= render "groups", groups: @budget.groups.order(:id) %>
|
|
||||||
</div>
|
|
||||||
|
|||||||
@@ -107,38 +107,56 @@ en:
|
|||||||
unable_notice: You cannot destroy a Budget that has associated investments
|
unable_notice: You cannot destroy a Budget that has associated investments
|
||||||
new:
|
new:
|
||||||
title: New participatory budget
|
title: New participatory budget
|
||||||
show:
|
|
||||||
groups:
|
|
||||||
one: 1 Group of budget headings
|
|
||||||
other: "%{count} Groups of budget headings"
|
|
||||||
form:
|
|
||||||
group: Group name
|
|
||||||
no_groups: No groups created yet. Each user will be able to vote in only one heading per group.
|
|
||||||
add_group: Add new group
|
|
||||||
create_group: Create group
|
|
||||||
edit_group: Edit group
|
|
||||||
submit: Save group
|
|
||||||
heading: Heading name
|
|
||||||
add_heading: Add heading
|
|
||||||
amount: Amount
|
|
||||||
population: "Population (optional)"
|
|
||||||
population_help_text: "This data is used exclusively to calculate the participation statistics"
|
|
||||||
save_heading: Save heading
|
|
||||||
no_heading: This group has no assigned heading.
|
|
||||||
table_heading: Heading
|
|
||||||
table_amount: Amount
|
|
||||||
table_population: Population
|
|
||||||
table_allow_custom_contents: Custom content allowed
|
|
||||||
population_info: "Budget Heading population field is used for Statistic purposes at the end of the Budget to show for each Heading that represents an area with population what percentage voted. The field is optional so you can leave it empty if it doesn't apply."
|
|
||||||
max_votable_headings: "Maximum number of headings in which a user can vote"
|
|
||||||
current_of_max_headings: "%{current} of %{max}"
|
|
||||||
allow_content_block: Allow content block
|
|
||||||
latitude: Latitude
|
|
||||||
longitude: Longitude
|
|
||||||
winners:
|
winners:
|
||||||
calculate: Calculate Winner Investments
|
calculate: Calculate Winner Investments
|
||||||
calculated: Winners being calculated, it may take a minute.
|
calculated: Winners being calculated, it may take a minute.
|
||||||
recalculate: Recalculate Winner Investments
|
recalculate: Recalculate Winner Investments
|
||||||
|
budget_groups:
|
||||||
|
name: "Name"
|
||||||
|
headings_name: "Headings"
|
||||||
|
headings_edit: "Edit Headings"
|
||||||
|
headings_manage: "Manage headings"
|
||||||
|
max_votable_headings: "Maximum number of headings in which a user can vote"
|
||||||
|
no_groups: "No groups created yet. Each user will be able to vote in only one heading per group."
|
||||||
|
amount:
|
||||||
|
one: "There is 1 group"
|
||||||
|
other: "There are %{count} groups"
|
||||||
|
create:
|
||||||
|
notice: "Group created successfully!"
|
||||||
|
update:
|
||||||
|
notice: "Group updated successfully"
|
||||||
|
destroy:
|
||||||
|
success_notice: "Group deleted successfully"
|
||||||
|
unable_notice: "You cannot destroy a Group that has associated headings"
|
||||||
|
form:
|
||||||
|
create: "Create new group"
|
||||||
|
edit: "Edit group"
|
||||||
|
name: "Group name"
|
||||||
|
submit: "Save group"
|
||||||
|
budget_headings:
|
||||||
|
name: "Name"
|
||||||
|
no_headings: "No headings created yet. Each user will be able to vote in only one heading per group."
|
||||||
|
amount:
|
||||||
|
one: "There is 1 heading"
|
||||||
|
other: "There are %{count} headings"
|
||||||
|
create:
|
||||||
|
notice: "Heading created successfully!"
|
||||||
|
update:
|
||||||
|
notice: "Heading updated successfully"
|
||||||
|
destroy:
|
||||||
|
success_notice: "Heading deleted successfully"
|
||||||
|
unable_notice: "You cannot destroy a Heading that has associated investments"
|
||||||
|
form:
|
||||||
|
name: "Heading name"
|
||||||
|
amount: "Amount"
|
||||||
|
population: "Population (optional)"
|
||||||
|
population_info: "Budget Heading population field is used for Statistic purposes at the end of the Budget to show for each Heading that represents an area with population what percentage voted. The field is optional so you can leave it empty if it doesn't apply."
|
||||||
|
latitude: "Latitude"
|
||||||
|
longitude: "Longitude"
|
||||||
|
allow_content_block: "Allow content block"
|
||||||
|
create: "Create new heading"
|
||||||
|
edit: "Edit heading"
|
||||||
|
submit: "Save heading"
|
||||||
budget_phases:
|
budget_phases:
|
||||||
edit:
|
edit:
|
||||||
start_date: Start date
|
start_date: Start date
|
||||||
|
|||||||
@@ -107,35 +107,56 @@ es:
|
|||||||
unable_notice: No se puede eliminar un presupuesto con proyectos asociados
|
unable_notice: No se puede eliminar un presupuesto con proyectos asociados
|
||||||
new:
|
new:
|
||||||
title: Nuevo presupuesto ciudadano
|
title: Nuevo presupuesto ciudadano
|
||||||
show:
|
|
||||||
groups:
|
|
||||||
one: 1 Grupo de partidas presupuestarias
|
|
||||||
other: "%{count} Grupos de partidas presupuestarias"
|
|
||||||
form:
|
|
||||||
group: Nombre del grupo
|
|
||||||
no_groups: No hay grupos creados todavía. Cada usuario podrá votar en una sola partida de cada grupo.
|
|
||||||
add_group: Añadir nuevo grupo
|
|
||||||
create_group: Crear grupo
|
|
||||||
edit_group: Editar grupo
|
|
||||||
submit: Guardar grupo
|
|
||||||
heading: Nombre de la partida
|
|
||||||
add_heading: Añadir partida
|
|
||||||
amount: Cantidad
|
|
||||||
population: "Población (opcional)"
|
|
||||||
population_help_text: "Este dato se utiliza exclusivamente para calcular las estadísticas de participación"
|
|
||||||
save_heading: Guardar partida
|
|
||||||
no_heading: Este grupo no tiene ninguna partida asignada.
|
|
||||||
table_heading: Partida
|
|
||||||
table_amount: Cantidad
|
|
||||||
table_population: Población
|
|
||||||
population_info: "El campo población de las partidas presupuestarias se usa con fines estadísticos únicamente, con el objetivo de mostrar el porcentaje de votos habidos en cada partida que represente un área con población. Es un campo opcional, así que puedes dejarlo en blanco si no aplica."
|
|
||||||
max_votable_headings: "Máximo número de partidas en que un usuario puede votar"
|
|
||||||
current_of_max_headings: "%{current} de %{max}"
|
|
||||||
allow_content_block: Permite bloque de contenidos
|
|
||||||
winners:
|
winners:
|
||||||
calculate: Calcular proyectos ganadores
|
calculate: Calcular proyectos ganadores
|
||||||
calculated: Calculando ganadores, puede tardar un minuto.
|
calculated: Calculando ganadores, puede tardar un minuto.
|
||||||
recalculate: Recalcular propuestas ganadoras
|
recalculate: Recalcular propuestas ganadoras
|
||||||
|
budget_groups:
|
||||||
|
name: "Nombre"
|
||||||
|
headings_name: "Partidas"
|
||||||
|
headings_edit: "Editar Partidas"
|
||||||
|
headings_manage: "Gestionar partidas"
|
||||||
|
max_votable_headings: "Máximo número de partidas en que un usuario puede votar"
|
||||||
|
no_groups: "No hay grupos creados todavía. Cada usuario podrá votar en una sola partida de cada grupo."
|
||||||
|
amount:
|
||||||
|
one: "Hay 1 grupo de partidas presupuestarias"
|
||||||
|
other: "Hay %{count} grupos de partidas presupuestarias"
|
||||||
|
create:
|
||||||
|
notice: "¡Grupo creado con éxito!"
|
||||||
|
update:
|
||||||
|
notice: "Grupo actualizado"
|
||||||
|
destroy:
|
||||||
|
success_notice: "Grupo eliminado correctamente"
|
||||||
|
unable_notice: "No se puede eliminar un grupo con partidas asociadas"
|
||||||
|
form:
|
||||||
|
create: "Crear nuevo grupo"
|
||||||
|
edit: "Editar grupo"
|
||||||
|
name: "Nombre del grupo"
|
||||||
|
submit: "Guardar grupo"
|
||||||
|
budget_headings:
|
||||||
|
name: "Nombre"
|
||||||
|
no_headings: "No hay partidas creadas todavía. Cada usuario podrá votar en una sola partida de cada grupo."
|
||||||
|
amount:
|
||||||
|
one: "Hay 1 partida presupuestarias"
|
||||||
|
other: "Hay %{count} partidas presupuestarias"
|
||||||
|
create:
|
||||||
|
notice: "¡Partida presupuestaria creada con éxito!"
|
||||||
|
update:
|
||||||
|
notice: "Partida presupuestaria actualizada"
|
||||||
|
destroy:
|
||||||
|
success_notice: "Partida presupuestaria eliminada correctamente"
|
||||||
|
unable_notice: "No se puede eliminar una partida presupuestaria con proyectos asociados"
|
||||||
|
form:
|
||||||
|
name: "Nombre de la partida"
|
||||||
|
amount: "Cantidad"
|
||||||
|
population: "Población (opcional)"
|
||||||
|
population_info: "El campo población de las partidas presupuestarias se usa con fines estadísticos únicamente, con el objetivo de mostrar el porcentaje de votos habidos en cada partida que represente un área con población. Es un campo opcional, así que puedes dejarlo en blanco si no aplica."
|
||||||
|
latitude: "Latitud"
|
||||||
|
longitude: "Longitud"
|
||||||
|
allow_content_block: "Permitir bloque de contenidos"
|
||||||
|
create: "Crear nueva partida"
|
||||||
|
edit: "Editar partida"
|
||||||
|
submit: "Guardar partida"
|
||||||
budget_phases:
|
budget_phases:
|
||||||
edit:
|
edit:
|
||||||
start_date: Fecha de Inicio
|
start_date: Fecha de Inicio
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ namespace :admin do
|
|||||||
put :calculate_winners
|
put :calculate_winners
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :budget_groups do
|
resources :groups, except: [:show], controller: "budget_groups" do
|
||||||
resources :budget_headings
|
resources :headings, except: [:show], controller: "budget_headings"
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :budget_investments, only: [:index, :show, :edit, :update] do
|
resources :budget_investments, only: [:index, :show, :edit, :update] do
|
||||||
|
|||||||
@@ -1,89 +1,177 @@
|
|||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
feature 'Admin can change the groups name' do
|
feature "Admin budget groups" do
|
||||||
|
|
||||||
let(:budget) { create(:budget, phase: 'drafting') }
|
let(:budget) { create(:budget, phase: "drafting") }
|
||||||
let(:group) { create(:budget_group, budget: budget) }
|
|
||||||
|
|
||||||
background do
|
background do
|
||||||
admin = create(:administrator)
|
admin = create(:administrator)
|
||||||
login_as(admin.user)
|
login_as(admin.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Show button" do
|
context "Feature flag" do
|
||||||
visit admin_budget_path(group.budget)
|
|
||||||
|
|
||||||
within("#budget_group_#{group.id}") do
|
|
||||||
expect(page).to have_content('Edit group')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Change name" do
|
|
||||||
group.update(name: 'Google')
|
|
||||||
expect(group.name).to eq('Google')
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Can change name when the budget isn't drafting, but the slug remains" do
|
|
||||||
old_slug = group.slug
|
|
||||||
budget.update(phase: 'reviewing')
|
|
||||||
group.update(name: 'Google')
|
|
||||||
|
|
||||||
expect(group.name).to eq('Google')
|
|
||||||
expect(group.slug).to eq old_slug
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario "Can't repeat names" do
|
|
||||||
budget.groups << create(:budget_group, name: 'group_name')
|
|
||||||
group.name = 'group_name'
|
|
||||||
|
|
||||||
expect(group).not_to be_valid
|
|
||||||
expect(group.errors.size).to eq(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "Maximum votable headings" do
|
|
||||||
|
|
||||||
background do
|
background do
|
||||||
3.times { create(:budget_heading, group: group) }
|
Setting["feature.budgets"] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Defaults to 1 heading per group", :js do
|
after do
|
||||||
visit admin_budget_path(group.budget)
|
Setting["feature.budgets"] = true
|
||||||
|
end
|
||||||
|
|
||||||
expect(page).to have_content('Maximum number of headings in which a user can vote 1 of 3')
|
scenario "Disabled with a feature flag" do
|
||||||
|
expect { visit admin_budget_groups_path(budget) }.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||||
|
end
|
||||||
|
|
||||||
within("#budget_group_#{group.id}") do
|
end
|
||||||
click_link 'Edit group'
|
|
||||||
|
|
||||||
expect(page).to have_select('budget_group_max_votable_headings', selected: '1')
|
context "Index" do
|
||||||
|
|
||||||
|
scenario "Displaying no groups for budget" do
|
||||||
|
visit admin_budget_groups_path(budget)
|
||||||
|
|
||||||
|
expect(page).to have_content "No groups created yet. Each user will be able to vote in only one heading per group."
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Displaying groups" do
|
||||||
|
group1 = create(:budget_group, budget: budget)
|
||||||
|
|
||||||
|
group2 = create(:budget_group, budget: budget)
|
||||||
|
create(:budget_heading, group: group2)
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
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 "Manage headings", href: admin_budget_group_headings_path(budget, group1)
|
||||||
|
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 "Manage headings", href: admin_budget_group_headings_path(budget, group2)
|
||||||
|
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 "Manage headings", href: admin_budget_group_headings_path(budget, group3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Update", :js do
|
scenario "Delete a group without headings" do
|
||||||
visit admin_budget_path(group.budget)
|
group = create(:budget_group, budget: budget)
|
||||||
|
|
||||||
within("#budget_group_#{group.id}") do
|
visit admin_budget_groups_path(budget)
|
||||||
click_link 'Edit group'
|
within("#budget_group_#{group.id}") { click_link "Delete" }
|
||||||
|
|
||||||
select '2', from: 'budget_group_max_votable_headings'
|
expect(page).to have_content "Group deleted successfully"
|
||||||
click_button 'Save group'
|
expect(page).not_to have_selector "#budget_group_#{group.id}"
|
||||||
end
|
|
||||||
|
|
||||||
expect(page).to have_content('Maximum number of headings in which a user can vote 2 of 3')
|
|
||||||
|
|
||||||
within("#budget_group_#{group.id}") do
|
|
||||||
click_link 'Edit group'
|
|
||||||
|
|
||||||
expect(page).to have_select('budget_group_max_votable_headings', selected: '2')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Do not display maximum votable headings' select in new form", :js do
|
scenario "Try to delete a group with headings" do
|
||||||
visit admin_budget_path(group.budget)
|
group = create(:budget_group, budget: budget)
|
||||||
|
create(:budget_heading, group: group)
|
||||||
|
|
||||||
click_link 'Add new group'
|
visit admin_budget_groups_path(budget)
|
||||||
|
within("#budget_group_#{group.id}") { click_link "Delete" }
|
||||||
|
|
||||||
expect(page).to have_field('budget_group_name')
|
expect(page).to have_content "You cannot destroy a Group that has associated headings"
|
||||||
expect(page).not_to have_field('budget_group_max_votable_headings')
|
expect(page).to have_selector "#budget_group_#{group.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "New" do
|
||||||
|
|
||||||
|
scenario "Create group" do
|
||||||
|
visit admin_budget_groups_path(budget)
|
||||||
|
click_link "Create new 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_link "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!"
|
||||||
|
expect(Budget::Group.first.max_votable_headings).to be 1
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Group name is mandatory" do
|
||||||
|
visit new_admin_budget_group_path(budget)
|
||||||
|
click_button "Create new group"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Group created successfully!"
|
||||||
|
expect(page).to have_css("label.error", text: "Group name")
|
||||||
|
expect(page).to have_content "can't be blank"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Edit" do
|
||||||
|
|
||||||
|
scenario "Show group information" do
|
||||||
|
group = create(:budget_group, budget: budget, 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" }
|
||||||
|
|
||||||
|
expect(page).to have_field "Group name", with: group.name
|
||||||
|
expect(page).to have_field "Maximum number of headings in which a user can vote", with: "2"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Update" do
|
||||||
|
let!(:group) { create(:budget_group, budget: budget, name: "All City") }
|
||||||
|
|
||||||
|
scenario "Updates group" do
|
||||||
|
2.times { create(:budget_heading, group: group) }
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_path(budget, group)
|
||||||
|
expect(page).to have_field "Group name", with: "All City"
|
||||||
|
|
||||||
|
fill_in "Group name", with: "Districts"
|
||||||
|
select "2", from: "Maximum number of headings in which a user can vote"
|
||||||
|
click_button "Edit group"
|
||||||
|
|
||||||
|
expect(page).to have_content "Group updated successfully"
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_path(budget, group)
|
||||||
|
expect(page).to have_field "Group name", with: "Districts"
|
||||||
|
expect(page).to have_field "Maximum number of headings in which a user can vote", with: "2"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Group name is already used" do
|
||||||
|
create(:budget_group, budget: budget, name: "Districts")
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_path(budget, group)
|
||||||
|
expect(page).to have_field "Group name", with: "All City"
|
||||||
|
|
||||||
|
fill_in "Group name", with: "Districts"
|
||||||
|
click_button "Edit group"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Group updated successfully"
|
||||||
|
expect(page).to have_css("label.error", text: "Group name")
|
||||||
|
expect(page).to have_content "has already been taken"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
208
spec/features/admin/budget_headings_spec.rb
Normal file
208
spec/features/admin/budget_headings_spec.rb
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
feature "Admin budget headings" do
|
||||||
|
|
||||||
|
let(:budget) { create(:budget, phase: "drafting") }
|
||||||
|
let(:group) { create(:budget_group, budget: budget) }
|
||||||
|
|
||||||
|
background do
|
||||||
|
admin = create(:administrator)
|
||||||
|
login_as(admin.user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Feature flag" do
|
||||||
|
|
||||||
|
background do
|
||||||
|
Setting["feature.budgets"] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
Setting["feature.budgets"] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Disabled with a feature flag" do
|
||||||
|
expect { visit admin_budget_group_headings_path(budget, group) }.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Index" do
|
||||||
|
|
||||||
|
scenario "Displaying no headings for group" do
|
||||||
|
visit admin_budget_group_headings_path(budget, group)
|
||||||
|
|
||||||
|
expect(page).to have_content "No headings created yet. Each user will be able to vote in only one heading per group."
|
||||||
|
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)
|
||||||
|
|
||||||
|
visit admin_budget_group_headings_path(budget, group)
|
||||||
|
expect(page).to have_content "There are 3 headings"
|
||||||
|
|
||||||
|
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", href: edit_admin_budget_group_heading_path(budget, group, heading1)
|
||||||
|
expect(page).to have_link "Delete", href: admin_budget_group_heading_path(budget, group, heading1)
|
||||||
|
end
|
||||||
|
|
||||||
|
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", href: edit_admin_budget_group_heading_path(budget, group, heading2)
|
||||||
|
expect(page).to have_link "Delete", href: admin_budget_group_heading_path(budget, group, heading2)
|
||||||
|
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", href: edit_admin_budget_group_heading_path(budget, group, heading3)
|
||||||
|
expect(page).to have_link "Delete", href: admin_budget_group_heading_path(budget, group, heading3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Delete a heading without investments" do
|
||||||
|
heading = create(:budget_heading, group: group)
|
||||||
|
|
||||||
|
visit admin_budget_group_headings_path(budget, group)
|
||||||
|
within("#budget_heading_#{heading.id}") { click_link "Delete" }
|
||||||
|
|
||||||
|
expect(page).to have_content "Heading deleted successfully"
|
||||||
|
expect(page).not_to have_selector "#budget_heading_#{heading.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Try to delete a heading with investments" do
|
||||||
|
heading = create(:budget_heading, group: group)
|
||||||
|
investment = create(:budget_investment, heading: heading)
|
||||||
|
|
||||||
|
visit admin_budget_group_headings_path(budget, group)
|
||||||
|
within("#budget_heading_#{heading.id}") { click_link "Delete" }
|
||||||
|
|
||||||
|
expect(page).to have_content "You cannot destroy a Heading that has associated investments"
|
||||||
|
expect(page).to have_selector "#budget_heading_#{heading.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "New" do
|
||||||
|
|
||||||
|
scenario "Create heading" do
|
||||||
|
visit admin_budget_group_headings_path(budget, group)
|
||||||
|
click_link "Create new heading"
|
||||||
|
|
||||||
|
fill_in "Heading name", with: "All City"
|
||||||
|
fill_in "Amount", with: "1000"
|
||||||
|
fill_in "Population (optional)", with: "10000"
|
||||||
|
check "Allow content block"
|
||||||
|
|
||||||
|
click_button "Create new heading"
|
||||||
|
|
||||||
|
expect(page).to have_content "Heading created successfully!"
|
||||||
|
expect(page).to have_link "All City"
|
||||||
|
expect(page).to have_content "€1,000"
|
||||||
|
expect(page).to have_content "10000"
|
||||||
|
expect(page).to have_content "Yes"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Heading name is mandatory" do
|
||||||
|
visit new_admin_budget_group_heading_path(budget, group)
|
||||||
|
click_button "Create new heading"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Heading created successfully!"
|
||||||
|
expect(page).to have_css("label.error", text: "Heading name")
|
||||||
|
expect(page).to have_content "can't be blank"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Heading amount is mandatory" do
|
||||||
|
visit new_admin_budget_group_heading_path(budget, group)
|
||||||
|
click_button "Create new heading"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Heading created successfully!"
|
||||||
|
expect(page).to have_css("label.error", text: "Amount")
|
||||||
|
expect(page).to have_content "can't be blank"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Edit" do
|
||||||
|
|
||||||
|
scenario "Show heading information" do
|
||||||
|
heading = create(:budget_heading, group: group)
|
||||||
|
|
||||||
|
visit admin_budget_group_headings_path(budget, group)
|
||||||
|
within("#budget_heading_#{heading.id}") { click_link "Edit" }
|
||||||
|
|
||||||
|
expect(page).to have_field "Heading name", with: heading.name
|
||||||
|
expect(page).to have_field "Amount", with: heading.price
|
||||||
|
expect(page).to have_field "Population (optional)", with: heading.population
|
||||||
|
expect(page).to have_field "Longitude", with: heading.longitude
|
||||||
|
expect(page).to have_field "Latitude", with: heading.latitude
|
||||||
|
expect(find_field("Allow content block")).not_to be_checked
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Update" do
|
||||||
|
let(:heading) { create(:budget_heading,
|
||||||
|
group: group,
|
||||||
|
name: "All City",
|
||||||
|
price: 1000,
|
||||||
|
population: 10000,
|
||||||
|
longitude: 20.50,
|
||||||
|
latitude: -10.50,
|
||||||
|
allow_custom_content: true) }
|
||||||
|
|
||||||
|
scenario "Updates group" do
|
||||||
|
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
||||||
|
|
||||||
|
expect(page).to have_field "Heading name", with: "All City"
|
||||||
|
expect(page).to have_field "Amount", with: 1000
|
||||||
|
expect(page).to have_field "Population (optional)", with: 10000
|
||||||
|
expect(page).to have_field "Longitude", with: 20.50
|
||||||
|
expect(page).to have_field "Latitude", with: -10.50
|
||||||
|
expect(find_field("Allow content block")).to be_checked
|
||||||
|
|
||||||
|
fill_in "Heading name", with: "Districts"
|
||||||
|
fill_in "Amount", with: "2000"
|
||||||
|
fill_in "Population (optional)", with: "20000"
|
||||||
|
fill_in "Longitude", with: "-40.47"
|
||||||
|
fill_in "Latitude", with: "25.25"
|
||||||
|
uncheck "Allow content block"
|
||||||
|
click_button "Edit heading"
|
||||||
|
|
||||||
|
expect(page).to have_content "Heading updated successfully"
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
||||||
|
expect(page).to have_field "Heading name", with: "Districts"
|
||||||
|
expect(page).to have_field "Amount", with: 2000
|
||||||
|
expect(page).to have_field "Population (optional)", with: 20000
|
||||||
|
expect(page).to have_field "Longitude", with: -40.47
|
||||||
|
expect(page).to have_field "Latitude", with: 25.25
|
||||||
|
expect(find_field("Allow content block")).not_to be_checked
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "Heading name is already used" do
|
||||||
|
create(:budget_heading, group: group, name: "Districts")
|
||||||
|
|
||||||
|
visit edit_admin_budget_group_heading_path(budget, group, heading)
|
||||||
|
expect(page).to have_field "Heading name", with: "All City"
|
||||||
|
|
||||||
|
fill_in "Heading name", with: "Districts"
|
||||||
|
click_button "Edit heading"
|
||||||
|
|
||||||
|
expect(page).not_to have_content "Heading updated successfully"
|
||||||
|
expect(page).to have_css("label.error", text: "Heading name")
|
||||||
|
expect(page).to have_content "has already been taken"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -227,109 +227,6 @@ feature 'Admin budgets' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Manage groups and headings' do
|
|
||||||
|
|
||||||
scenario 'Create group', :js do
|
|
||||||
budget = create(:budget, name: 'Yearly budget')
|
|
||||||
|
|
||||||
visit admin_budgets_path
|
|
||||||
|
|
||||||
within("#budget_#{budget.id}") do
|
|
||||||
click_link 'Edit headings groups'
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(page).to have_content '0 Groups of budget headings'
|
|
||||||
expect(page).to have_content 'No groups created yet.'
|
|
||||||
|
|
||||||
click_link 'Add new group'
|
|
||||||
|
|
||||||
fill_in 'budget_group_name', with: 'Health'
|
|
||||||
click_button 'Create group'
|
|
||||||
|
|
||||||
expect(page).to have_content '1 Group of budget headings'
|
|
||||||
expect(page).to have_content 'Health'
|
|
||||||
expect(page).to have_content 'Yearly budget'
|
|
||||||
expect(page).not_to have_content 'No groups created yet.'
|
|
||||||
|
|
||||||
visit admin_budgets_path
|
|
||||||
within("#budget_#{budget.id}") do
|
|
||||||
click_link 'Edit headings groups'
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(page).to have_content '1 Group of budget headings'
|
|
||||||
expect(page).to have_content 'Health'
|
|
||||||
expect(page).to have_content 'Yearly budget'
|
|
||||||
expect(page).not_to have_content 'No groups created yet.'
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario 'Create heading', :js do
|
|
||||||
budget = create(:budget, name: 'Yearly budget')
|
|
||||||
group = create(:budget_group, budget: budget, name: 'Districts improvments')
|
|
||||||
|
|
||||||
visit admin_budget_path(budget)
|
|
||||||
|
|
||||||
within("#budget_group_#{group.id}") do
|
|
||||||
expect(page).to have_content 'This group has no assigned heading.'
|
|
||||||
click_link 'Add heading'
|
|
||||||
|
|
||||||
fill_in 'budget_heading_name', with: 'District 9 reconstruction'
|
|
||||||
fill_in 'budget_heading_price', with: '6785'
|
|
||||||
fill_in 'budget_heading_population', with: '100500'
|
|
||||||
fill_in 'budget_heading_latitude', with: '40.416775'
|
|
||||||
fill_in 'budget_heading_longitude', with: '-3.703790'
|
|
||||||
click_button 'Save heading'
|
|
||||||
end
|
|
||||||
|
|
||||||
visit admin_budget_path(budget)
|
|
||||||
|
|
||||||
within("#budget_group_#{group.id}") do
|
|
||||||
expect(page).not_to have_content 'This group has no assigned heading.'
|
|
||||||
expect(page).to have_content 'District 9 reconstruction'
|
|
||||||
expect(page).to have_content '€6,785'
|
|
||||||
expect(page).to have_content '100500'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario 'Update heading', :js do
|
|
||||||
budget = create(:budget, name: 'Yearly budget')
|
|
||||||
group = create(:budget_group, budget: budget, name: 'Districts improvments')
|
|
||||||
heading = create(:budget_heading, group: group, name: "District 1")
|
|
||||||
heading = create(:budget_heading, group: group, name: "District 3")
|
|
||||||
|
|
||||||
visit admin_budget_path(budget)
|
|
||||||
|
|
||||||
within("#heading-#{heading.id}") do
|
|
||||||
click_link 'Edit'
|
|
||||||
|
|
||||||
fill_in 'budget_heading_name', with: 'District 2'
|
|
||||||
fill_in 'budget_heading_price', with: '10000'
|
|
||||||
fill_in 'budget_heading_population', with: '6000'
|
|
||||||
click_button 'Save heading'
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(page).to have_content 'District 2'
|
|
||||||
expect(page).to have_content '€10,000'
|
|
||||||
expect(page).to have_content '6000'
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario 'Delete heading', :js do
|
|
||||||
budget = create(:budget, name: 'Yearly budget')
|
|
||||||
group = create(:budget_group, budget: budget, name: 'Districts improvments')
|
|
||||||
heading = create(:budget_heading, group: group, name: "District 1")
|
|
||||||
|
|
||||||
visit admin_budget_path(budget)
|
|
||||||
|
|
||||||
expect(page).to have_content 'District 1'
|
|
||||||
|
|
||||||
within("#heading-#{heading.id}") do
|
|
||||||
click_link 'Delete'
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(page).not_to have_content 'District 1'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def translated_phase_name(phase_kind: kind)
|
def translated_phase_name(phase_kind: kind)
|
||||||
|
|||||||
@@ -161,6 +161,34 @@ feature 'Ballots' do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario "the Map shoud be visible before and after", :js do
|
||||||
|
investment = create(:budget_investment, :selected, heading: new_york, price: 10000)
|
||||||
|
|
||||||
|
visit budget_path(budget)
|
||||||
|
click_link "States"
|
||||||
|
click_link "New York"
|
||||||
|
|
||||||
|
within("#sidebar") do
|
||||||
|
expect(page).to have_content "OpenStreetMap"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_to_ballot(investment)
|
||||||
|
|
||||||
|
within("#sidebar") do
|
||||||
|
expect(page).to have_content investment.title
|
||||||
|
expect(page).to have_content "OpenStreetMap"
|
||||||
|
end
|
||||||
|
|
||||||
|
within("#budget_investment_#{investment.id}") do
|
||||||
|
click_link "Remove vote"
|
||||||
|
end
|
||||||
|
|
||||||
|
within("#sidebar") do
|
||||||
|
expect(page).not_to have_content investment.title
|
||||||
|
expect(page).to have_content "OpenStreetMap"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#Break up or simplify with helpers
|
#Break up or simplify with helpers
|
||||||
|
|||||||
Reference in New Issue
Block a user