Merge pull request #4269 from consul/sdg_management
Add SDG content management section
This commit is contained in:
@@ -36,7 +36,8 @@
|
||||
}
|
||||
|
||||
&.budgets-link,
|
||||
&.investments-link {
|
||||
&.investments-link,
|
||||
&.budget-investments-link {
|
||||
@include icon(chart-pie, solid);
|
||||
}
|
||||
|
||||
@@ -56,7 +57,8 @@
|
||||
@include icon(envelope, regular);
|
||||
}
|
||||
|
||||
&.legislation-link {
|
||||
&.legislation-link,
|
||||
&.legislation-processes-link {
|
||||
@include icon(file-alt, solid);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
.admin [role=search] {
|
||||
display: flex;
|
||||
|
||||
&.complex {
|
||||
@include breakpoint(small only) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
select {
|
||||
height: $line-height * 2;
|
||||
margin: 0 rem-calc(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.complex) {
|
||||
@include breakpoint(medium) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
[type="submit"] {
|
||||
@include button($background: $link);
|
||||
border-radius: 0;
|
||||
@@ -10,8 +29,4 @@
|
||||
@include button-disabled;
|
||||
}
|
||||
}
|
||||
|
||||
@include breakpoint(medium) {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<%= form_tag(url, options) do |f| %>
|
||||
<%= text_field_tag :search, search_terms.to_s, placeholder: label, "aria-label": label %>
|
||||
<%= content %>
|
||||
<%= submit_tag t("admin.shared.search.search") %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,9 +1 @@
|
||||
<%= link_list(
|
||||
[
|
||||
t("sdg_management.menu.sdg_content"),
|
||||
sdg_management_goals_path,
|
||||
sdg?,
|
||||
class: "goals-link"
|
||||
],
|
||||
class: "sdg-content-menu"
|
||||
) %>
|
||||
<%= link_list(*links, class: "sdg-content-menu") %>
|
||||
|
||||
@@ -3,7 +3,50 @@ class SDGManagement::MenuComponent < ApplicationComponent
|
||||
|
||||
private
|
||||
|
||||
def links
|
||||
[goals_link, *relatable_links]
|
||||
end
|
||||
|
||||
def goals_link
|
||||
[t("sdg_management.menu.sdg_content"), sdg_management_goals_path, sdg?, class: "goals-link"]
|
||||
end
|
||||
|
||||
def relatable_links
|
||||
SDG::Related::RELATABLE_TYPES.map do |type|
|
||||
next unless setting["process.#{process_name(type)}"] && setting["sdg.process.#{process_name(type)}"]
|
||||
|
||||
[
|
||||
t("sdg_management.menu.#{table_name(type)}"),
|
||||
relatable_type_path(type),
|
||||
controller_name == "relations" && params[:relatable_type] == type.tableize,
|
||||
class: "#{table_name(type).tr("_", "-")}-link"
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
def sdg?
|
||||
%w[goals targets local_targets].include?(controller_name)
|
||||
end
|
||||
|
||||
def relatable_type_path(type)
|
||||
{
|
||||
controller: "sdg_management/relations",
|
||||
action: :index,
|
||||
relatable_type: type.tableize
|
||||
}
|
||||
end
|
||||
|
||||
def table_name(type)
|
||||
type.constantize.table_name
|
||||
end
|
||||
|
||||
def process_name(type)
|
||||
process_name = type.split("::").first
|
||||
|
||||
if process_name == "Legislation"
|
||||
"legislation"
|
||||
else
|
||||
process_name.constantize.table_name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<%= header %>
|
||||
|
||||
<%= form_for record, url: update_path do |f| %>
|
||||
<%= f.text_field :sdg_target_list %>
|
||||
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
24
app/components/sdg_management/relations/edit_component.rb
Normal file
24
app/components/sdg_management/relations/edit_component.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
class SDGManagement::Relations::EditComponent < ApplicationComponent
|
||||
include Header
|
||||
|
||||
attr_reader :record
|
||||
|
||||
def initialize(record)
|
||||
@record = record
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def title
|
||||
@record.title
|
||||
end
|
||||
|
||||
def update_path
|
||||
{
|
||||
controller: "sdg_management/relations",
|
||||
action: :update,
|
||||
relatable_type: record.class.name.tableize,
|
||||
id: record
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
<%= header %>
|
||||
|
||||
<%= render Admin::SearchComponent.new(label: search_label, class: "complex") do |component| %>
|
||||
<%= component.select_tag :goal_code, goal_options,
|
||||
include_blank: goal_blank_option,
|
||||
"aria-label": goal_label %>
|
||||
<%= component.select_tag :target_code, target_options,
|
||||
include_blank: target_blank_option,
|
||||
"aria-label": target_label %>
|
||||
<% end %>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= model_class.human_attribute_name(:title) %></th>
|
||||
<th><%= SDG::Goal.model_name.human(count: 2).upcase_first %></th>
|
||||
<th><%= SDG::Target.model_name.human(count: 2).upcase_first %></th>
|
||||
<th><%= t("admin.actions.actions") %></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @records.each do |record| %>
|
||||
<tr>
|
||||
<td><%= record.title %></td>
|
||||
<td><%= record.sdg_goal_list %></td>
|
||||
<td><%= record.sdg_target_list %></td>
|
||||
<td>
|
||||
<%= render Admin::TableActionsComponent.new(
|
||||
record,
|
||||
actions: [:edit],
|
||||
edit_text: t("sdg_management.actions.edit"),
|
||||
edit_path: edit_path_for(record)
|
||||
) %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= paginate(@records) %>
|
||||
56
app/components/sdg_management/relations/index_component.rb
Normal file
56
app/components/sdg_management/relations/index_component.rb
Normal file
@@ -0,0 +1,56 @@
|
||||
class SDGManagement::Relations::IndexComponent < ApplicationComponent
|
||||
include Header
|
||||
|
||||
attr_reader :records
|
||||
|
||||
def initialize(records)
|
||||
@records = records
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def title
|
||||
t("sdg_management.menu.#{model_class.table_name}")
|
||||
end
|
||||
|
||||
def model_class
|
||||
records.model
|
||||
end
|
||||
|
||||
def edit_path_for(record)
|
||||
{
|
||||
controller: "sdg_management/relations",
|
||||
action: :edit,
|
||||
relatable_type: record.class.name.tableize,
|
||||
id: record
|
||||
}
|
||||
end
|
||||
|
||||
def search_label
|
||||
t("admin.shared.search.label.#{model_class.table_name}")
|
||||
end
|
||||
|
||||
def goal_label
|
||||
t("admin.shared.search.advanced_filters.sdg_goals.label")
|
||||
end
|
||||
|
||||
def goal_blank_option
|
||||
t("admin.shared.search.advanced_filters.sdg_goals.all")
|
||||
end
|
||||
|
||||
def target_label
|
||||
t("admin.shared.search.advanced_filters.sdg_targets.label")
|
||||
end
|
||||
|
||||
def target_blank_option
|
||||
t("admin.shared.search.advanced_filters.sdg_targets.all")
|
||||
end
|
||||
|
||||
def goal_options
|
||||
options_from_collection_for_select(SDG::Goal.all, :code, :code_and_title, params[:goal_code])
|
||||
end
|
||||
|
||||
def target_options
|
||||
options_from_collection_for_select(SDG::Target.all.sort, :code, :code, params[:target_code])
|
||||
end
|
||||
end
|
||||
@@ -13,7 +13,7 @@
|
||||
<% targets.group_by(&:goal).map do |goal, targets| %>
|
||||
<tr class="goal-header">
|
||||
<th id="<%= header_id(goal) %>" colspan="2" scope="colgroup">
|
||||
<%= goal.code %>. <%= goal.title %>
|
||||
<%= goal.code_and_title %>
|
||||
</th>
|
||||
</tr>
|
||||
|
||||
|
||||
42
app/controllers/sdg_management/relations_controller.rb
Normal file
42
app/controllers/sdg_management/relations_controller.rb
Normal file
@@ -0,0 +1,42 @@
|
||||
class SDGManagement::RelationsController < SDGManagement::BaseController
|
||||
before_action :check_feature_flags
|
||||
before_action :load_record, only: [:edit, :update]
|
||||
|
||||
def index
|
||||
@records = relatable_class
|
||||
.accessible_by(current_ability)
|
||||
.by_goal(params[:goal_code])
|
||||
.by_target(params[:target_code])
|
||||
.order(:id)
|
||||
.page(params[:page])
|
||||
|
||||
@records = @records.search(params[:search]) if params[:search].present?
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@record.sdg_target_list = params[@record.class.table_name.singularize][:sdg_target_list]
|
||||
|
||||
redirect_to action: :index
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_record
|
||||
@record = relatable_class.find(params[:id])
|
||||
end
|
||||
|
||||
def relatable_class
|
||||
params[:relatable_type].classify.constantize
|
||||
end
|
||||
|
||||
def check_feature_flags
|
||||
process_name = params[:relatable_type].split("/").first
|
||||
process_name = process_name.pluralize unless process_name == "legislation"
|
||||
|
||||
check_feature_flag(process_name)
|
||||
raise FeatureDisabled, process_name unless Setting["sdg.process.#{process_name}"]
|
||||
end
|
||||
end
|
||||
@@ -12,7 +12,40 @@ module SDG::Relatable
|
||||
end
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def by_goal(code)
|
||||
by_sdg_related(SDG::Goal, code)
|
||||
end
|
||||
|
||||
def by_target(code)
|
||||
by_sdg_related(SDG::Target, code)
|
||||
end
|
||||
|
||||
def by_sdg_related(sdg_class, code)
|
||||
return all if code.blank?
|
||||
|
||||
joins(sdg_class.table_name.to_sym).merge(sdg_class.where(code: code))
|
||||
end
|
||||
end
|
||||
|
||||
def related_sdgs
|
||||
sdg_relations.map(&:related_sdg)
|
||||
end
|
||||
|
||||
def sdg_goal_list
|
||||
sdg_goals.order(:code).map(&:code).join(", ")
|
||||
end
|
||||
|
||||
def sdg_target_list
|
||||
sdg_targets.sort.map(&:code).join(", ")
|
||||
end
|
||||
|
||||
def sdg_target_list=(codes)
|
||||
targets = codes.tr(" ", "").split(",").map { |code| SDG::Target[code] }
|
||||
|
||||
transaction do
|
||||
self.sdg_targets = targets
|
||||
self.sdg_goals = targets.map(&:goal).uniq
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ class Legislation::Process < ApplicationRecord
|
||||
include Imageable
|
||||
include Documentable
|
||||
include SDG::Relatable
|
||||
include Searchable
|
||||
|
||||
acts_as_paranoid column: :hidden_at
|
||||
acts_as_taggable_on :customs
|
||||
@@ -123,6 +124,22 @@ class Legislation::Process < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def searchable_translations_definitions
|
||||
{
|
||||
title => "A",
|
||||
summary => "C",
|
||||
description => "D"
|
||||
}
|
||||
end
|
||||
|
||||
def searchable_values
|
||||
searchable_globalized_values
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
pg_search(terms)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_date_ranges
|
||||
|
||||
@@ -5,6 +5,7 @@ class Poll < ApplicationRecord
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
include Notifiable
|
||||
include Searchable
|
||||
include Sluggable
|
||||
include StatsVersionable
|
||||
include Reportable
|
||||
@@ -175,4 +176,20 @@ class Poll < ApplicationRecord
|
||||
def budget_poll?
|
||||
budget.present?
|
||||
end
|
||||
|
||||
def searchable_translations_definitions
|
||||
{
|
||||
name => "A",
|
||||
summary => "C",
|
||||
description => "D"
|
||||
}
|
||||
end
|
||||
|
||||
def searchable_values
|
||||
searchable_globalized_values
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
pg_search(terms)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,4 +16,8 @@ class SDG::Goal < ApplicationRecord
|
||||
def self.[](code)
|
||||
find_by!(code: code)
|
||||
end
|
||||
|
||||
def code_and_title
|
||||
"#{code}. #{title}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<h2><%= t("admin.debates.index.title") %></h2>
|
||||
|
||||
<% if @debates.any? %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.debate_search.placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.search.label.debates")) %>
|
||||
|
||||
<h3 class="inline-block"><%= page_entries_info @debates %></h3>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
class: "button float-right hollow" %>
|
||||
|
||||
<%= render Admin::SearchComponent.new(
|
||||
label: t("admin.local_census_records.index.search.placeholder"),
|
||||
label: t("admin.shared.search.label.local_census_records"),
|
||||
remote: true
|
||||
) %>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<%= render Admin::SearchComponent.new(
|
||||
url: search_admin_organizations_path,
|
||||
label: t("admin.organizations.index.search_placeholder")
|
||||
label: t("admin.shared.search.label.organizations")
|
||||
) %>
|
||||
|
||||
<%= render "shared/filter_subnav", i18n_namespace: "admin.organizations.index" %>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h2><%= t("admin.organizations.search.title") %></h2>
|
||||
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.organizations.index.search_placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.search.label.organizations")) %>
|
||||
|
||||
<div id="search-results">
|
||||
<% if @organizations.any? %>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="input-group">
|
||||
<%= text_field_tag :search,
|
||||
@search,
|
||||
placeholder: t("admin.shared.booths_search.placeholder"), id: "search-booths" %>
|
||||
placeholder: t("admin.shared.search.label.booths"), id: "search-booths" %>
|
||||
<div class="input-group-button">
|
||||
<%= submit_tag t("admin.shared.search.search"), class: "button" %>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<%= link_to t("admin.booths.index.add_booth"), new_admin_booth_path, class: "button float-right" %>
|
||||
<% end %>
|
||||
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.booths_search.placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.search.label.booths")) %>
|
||||
|
||||
<% if @booths.empty? %>
|
||||
<div class="callout primary">
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div class="input-group">
|
||||
<%= text_field_tag :search,
|
||||
@search,
|
||||
placeholder: t("admin.shared.poll_officers_search.placeholder"), id: "search-officers" %>
|
||||
placeholder: t("admin.shared.search.label.poll_officers"), id: "search-officers" %>
|
||||
<div class="input-group-button">
|
||||
<%= submit_tag t("admin.shared.search.search"), class: "button" %>
|
||||
</div>
|
||||
|
||||
@@ -1 +1 @@
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.poll_questions_search.placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.search.label.poll_questions")) %>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<h2><%= t("admin.proposals.index.title") %></h2>
|
||||
|
||||
<% if @proposals.any? %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.proposal_search.placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.search.label.proposals")) %>
|
||||
|
||||
<h3><%= page_entries_info @proposals %></h3>
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
<%= render Admin::SearchComponent.new(url: url, label: t("admin.shared.user_search.placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(url: url, label: t("admin.shared.search.label.users")) %>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<main>
|
||||
<h2><%= t("management.proposals.index.title") %></h2>
|
||||
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.proposal_search.placeholder")) %>
|
||||
<%= render Admin::SearchComponent.new(label: t("admin.shared.search.label.proposals")) %>
|
||||
|
||||
<div class="management-list">
|
||||
<div class="proposals-list">
|
||||
|
||||
1
app/views/sdg_management/relations/edit.html.erb
Normal file
1
app/views/sdg_management/relations/edit.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= render SDGManagement::Relations::EditComponent.new(@record) %>
|
||||
1
app/views/sdg_management/relations/index.html.erb
Normal file
1
app/views/sdg_management/relations/index.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<%= render SDGManagement::Relations::IndexComponent.new(@records) %>
|
||||
@@ -2,6 +2,7 @@ en:
|
||||
attributes:
|
||||
geozone_id: "Scope of operation"
|
||||
results_enabled: "Show results"
|
||||
sdg_target_list: "Targets"
|
||||
stats_enabled: "Show stats"
|
||||
advanced_stats_enabled: "Show advanced stats"
|
||||
name: Name
|
||||
@@ -287,6 +288,7 @@ en:
|
||||
responsible_name: "Person responsible for the group"
|
||||
poll:
|
||||
name: "Name"
|
||||
title: "Name"
|
||||
starts_at: "Start Date"
|
||||
ends_at: "Closing Date"
|
||||
geozone_restricted: "Restricted by geozone"
|
||||
|
||||
@@ -1169,7 +1169,6 @@ en:
|
||||
no_organizations: There are no organizations.
|
||||
reject: Reject
|
||||
rejected: Rejected
|
||||
search_placeholder: Name, email or phone number
|
||||
title: Organisations
|
||||
verified: Verified
|
||||
verify: Verify
|
||||
@@ -1254,19 +1253,26 @@ en:
|
||||
true_value: "Yes"
|
||||
false_value: "No"
|
||||
search:
|
||||
advanced_filters:
|
||||
sdg_goals:
|
||||
all: "All goals"
|
||||
label: "By goal"
|
||||
sdg_targets:
|
||||
all: "All targets"
|
||||
label: "By target"
|
||||
label:
|
||||
booths: "Search booth by name or location"
|
||||
budget_investments: "Search investments by title, description or heading"
|
||||
debates: "Search debates by title or description"
|
||||
legislation_processes: "Search processes by title or description"
|
||||
local_census_records: "Search by document number"
|
||||
organizations: "Name, email or phone number"
|
||||
poll_officers: "Search poll officers"
|
||||
poll_questions: "Search poll questions"
|
||||
polls: "Search polls by name or description"
|
||||
proposals: "Search proposals by title, code, description or question"
|
||||
users: "Search user by name or email"
|
||||
search: "Search"
|
||||
booths_search:
|
||||
placeholder: Search booth by name or location
|
||||
poll_officers_search:
|
||||
placeholder: Search poll officers
|
||||
poll_questions_search:
|
||||
placeholder: Search poll questions
|
||||
proposal_search:
|
||||
placeholder: Search proposals by title, code, description or question
|
||||
debate_search:
|
||||
placeholder: Search debates by title or description
|
||||
user_search:
|
||||
placeholder: Search user by name or email
|
||||
search_results: "Search results"
|
||||
no_search_results: "No results found."
|
||||
actions: Actions
|
||||
@@ -1572,8 +1578,6 @@ en:
|
||||
document_number: Document number
|
||||
date_of_birth: Date of birth
|
||||
postal_code: Postal code
|
||||
search:
|
||||
placeholder: Search by document number
|
||||
import: Import CSV
|
||||
new:
|
||||
creating: Creating new local census record
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
en:
|
||||
sdg_management:
|
||||
actions:
|
||||
edit: "Manage goals and targets"
|
||||
header:
|
||||
title: "SDG content"
|
||||
menu:
|
||||
budget_investments: "Participatory budgets"
|
||||
debates: "Debates"
|
||||
legislation_processes: "Collaborative legislation"
|
||||
polls: "Polls"
|
||||
proposals: "Proposals"
|
||||
sdg_content: "Goals and Targets"
|
||||
local_targets:
|
||||
create:
|
||||
|
||||
@@ -2,6 +2,7 @@ es:
|
||||
attributes:
|
||||
geozone_id: "Ámbito de actuación"
|
||||
results_enabled: "Mostrar resultados"
|
||||
sdg_target_list: "Metas"
|
||||
stats_enabled: "Mostrar estadísticas"
|
||||
advanced_stats_enabled: "Mostrar estadísticas avanzadas"
|
||||
name: Nombre
|
||||
@@ -287,6 +288,7 @@ es:
|
||||
responsible_name: "Persona responsable del colectivo"
|
||||
poll:
|
||||
name: "Nombre"
|
||||
title: "Nombre"
|
||||
starts_at: "Fecha de apertura"
|
||||
ends_at: "Fecha de cierre"
|
||||
geozone_restricted: "Restringida por zonas"
|
||||
|
||||
@@ -1168,7 +1168,6 @@ es:
|
||||
no_organizations: No hay organizaciones.
|
||||
reject: Rechazar
|
||||
rejected: Rechazada
|
||||
search_placeholder: Nombre, email o teléfono
|
||||
title: Organizaciones
|
||||
verified: Verificada
|
||||
verify: Verificar
|
||||
@@ -1253,19 +1252,26 @@ es:
|
||||
true_value: "Sí"
|
||||
false_value: "No"
|
||||
search:
|
||||
advanced_filters:
|
||||
sdg_goals:
|
||||
all: "Todos los objetivos"
|
||||
label: "Por objetivo"
|
||||
sdg_targets:
|
||||
all: "Todas las metas"
|
||||
label: "Por meta"
|
||||
label:
|
||||
booths: "Buscar urna por nombre"
|
||||
budget_investments: "Buscar proyectos por título, descripción o partida"
|
||||
debates: "Buscar debates por título o descripción"
|
||||
legislation_processes: "Buscar procesos por título o descripción"
|
||||
local_census_records: "Búsqueda por número de documento"
|
||||
organizations: "Nombre, email o teléfono"
|
||||
poll_officers: "Buscar presidentes de mesa"
|
||||
poll_questions: "Buscar preguntas"
|
||||
polls: "Buscar votaciones por nombre o descripción"
|
||||
proposals: "Buscar propuestas por título, código, descripción o pregunta"
|
||||
users: "Buscar usuario por nombre o email"
|
||||
search: "Buscar"
|
||||
booths_search:
|
||||
placeholder: Buscar urna por nombre
|
||||
poll_officers_search:
|
||||
placeholder: Buscar presidentes de mesa
|
||||
poll_questions_search:
|
||||
placeholder: Buscar preguntas
|
||||
proposal_search:
|
||||
placeholder: Buscar propuestas por título, código, descripción o pregunta
|
||||
debate_search:
|
||||
placeholder: Buscar debates por título o descripción
|
||||
user_search:
|
||||
placeholder: Buscar usuario por nombre o email
|
||||
search_results: "Resultados de la búsqueda"
|
||||
no_search_results: "No se han encontrado resultados."
|
||||
actions: Acciones
|
||||
@@ -1571,8 +1577,6 @@ es:
|
||||
document_number: Número de documento
|
||||
date_of_birth: Fecha de nacimiento
|
||||
postal_code: Código postal
|
||||
search:
|
||||
placeholder: Búsqueda por número de documento
|
||||
import: Importar CSV
|
||||
new:
|
||||
creating: Creando nuevo registro de censo local
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
es:
|
||||
sdg_management:
|
||||
actions:
|
||||
edit: "Asignar objetivos y metas"
|
||||
header:
|
||||
title: "Contenido ODS"
|
||||
menu:
|
||||
budget_investments: "Presupuestos participativos"
|
||||
debates: "Debates"
|
||||
legislation_processes: "Legislación colaborativa"
|
||||
polls: "Votaciones"
|
||||
proposals: "Propuestas"
|
||||
sdg_content: "Objetivos y Metas"
|
||||
local_targets:
|
||||
create:
|
||||
|
||||
@@ -4,4 +4,16 @@ namespace :sdg_management do
|
||||
resources :goals, only: [:index]
|
||||
resources :targets, only: [:index]
|
||||
resources :local_targets, except: [:show]
|
||||
|
||||
types = SDG::Related::RELATABLE_TYPES.map(&:tableize)
|
||||
types_constraint = /#{types.join("|")}/
|
||||
|
||||
get "*relatable_type", to: "relations#index", as: "relations", relatable_type: types_constraint
|
||||
get "*relatable_type/:id/edit", to: "relations#edit", as: "edit_relation", relatable_type: types_constraint
|
||||
patch "*relatable_type/:id", to: "relations#update", as: "relation", relatable_type: types_constraint
|
||||
|
||||
types.each do |type|
|
||||
get type, to: "relations#index", as: type
|
||||
get "#{type}/:id/edit", to: "relations#edit", as: "edit_#{type.singularize}"
|
||||
end
|
||||
end
|
||||
|
||||
5
db/migrate/20201216132234_add_tsv_to_polls.rb
Normal file
5
db/migrate/20201216132234_add_tsv_to_polls.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddTsvToPolls < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :polls, :tsv, :tsvector
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddTsvToLegislationProcesses < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :legislation_processes, :tsv, :tsvector
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2020_11_24_145559) do
|
||||
ActiveRecord::Schema.define(version: 2020_12_16_132642) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_trgm"
|
||||
@@ -747,6 +747,7 @@ ActiveRecord::Schema.define(version: 2020_11_24_145559) do
|
||||
t.boolean "homepage_enabled", default: false
|
||||
t.text "background_color"
|
||||
t.text "font_color"
|
||||
t.tsvector "tsv"
|
||||
t.index ["allegations_end_date"], name: "index_legislation_processes_on_allegations_end_date"
|
||||
t.index ["allegations_start_date"], name: "index_legislation_processes_on_allegations_start_date"
|
||||
t.index ["debate_end_date"], name: "index_legislation_processes_on_debate_end_date"
|
||||
@@ -1166,6 +1167,7 @@ ActiveRecord::Schema.define(version: 2020_11_24_145559) do
|
||||
t.integer "budget_id"
|
||||
t.string "related_type"
|
||||
t.integer "related_id"
|
||||
t.tsvector "tsv"
|
||||
t.index ["budget_id"], name: "index_polls_on_budget_id", unique: true
|
||||
t.index ["related_type", "related_id"], name: "index_polls_on_related_type_and_related_id"
|
||||
t.index ["starts_at", "ends_at"], name: "index_polls_on_starts_at_and_ends_at"
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace :consul do
|
||||
|
||||
desc "Runs tasks needed to upgrade from 1.2.0 to 1.3.0"
|
||||
task "execute_release_1.3.0_tasks": [
|
||||
"db:load_sdg"
|
||||
"db:load_sdg",
|
||||
"db:calculate_tsv"
|
||||
]
|
||||
end
|
||||
|
||||
@@ -10,4 +10,10 @@ namespace :db do
|
||||
ApplicationLogger.new.info "Adding Sustainable Development Goals content"
|
||||
load(Rails.root.join("db", "sdg.rb"))
|
||||
end
|
||||
|
||||
desc "Calculates the TSV column for all polls and legislation processes"
|
||||
task calculate_tsv: :environment do
|
||||
Poll.find_each(&:calculate_tsvector)
|
||||
Legislation::Process.find_each(&:calculate_tsvector)
|
||||
end
|
||||
end
|
||||
|
||||
92
spec/components/sdg_management/menu_component_spec.rb
Normal file
92
spec/components/sdg_management/menu_component_spec.rb
Normal file
@@ -0,0 +1,92 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe SDGManagement::MenuComponent, type: :component do
|
||||
let(:component) { SDGManagement::MenuComponent.new }
|
||||
|
||||
before do
|
||||
Setting["sdg.process.budgets"] = true
|
||||
Setting["sdg.process.debates"] = true
|
||||
Setting["sdg.process.legislation"] = true
|
||||
Setting["sdg.process.polls"] = true
|
||||
Setting["sdg.process.proposals"] = true
|
||||
end
|
||||
|
||||
context "processes enabled" do
|
||||
it "generates links to all processes" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_link "Goals and Targets"
|
||||
expect(page).to have_link "Participatory budgets"
|
||||
expect(page).to have_link "Debates"
|
||||
expect(page).to have_link "Collaborative legislation"
|
||||
expect(page).to have_link "Polls"
|
||||
expect(page).to have_link "Proposals"
|
||||
end
|
||||
end
|
||||
|
||||
context "processes disabled" do
|
||||
before do
|
||||
Setting["process.budgets"] = false
|
||||
Setting["process.debates"] = false
|
||||
Setting["process.legislation"] = false
|
||||
Setting["process.polls"] = false
|
||||
Setting["process.proposals"] = false
|
||||
end
|
||||
|
||||
it "does not generate links to any processes" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "a", count: 1
|
||||
expect(page).to have_link "Goals and Targets"
|
||||
end
|
||||
end
|
||||
|
||||
context "SDG processes disabled" do
|
||||
before do
|
||||
Setting["sdg.process.budgets"] = false
|
||||
Setting["sdg.process.debates"] = false
|
||||
Setting["sdg.process.legislation"] = false
|
||||
Setting["sdg.process.polls"] = false
|
||||
Setting["sdg.process.proposals"] = false
|
||||
end
|
||||
|
||||
it "does not generate links to any processes" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_css "a", count: 1
|
||||
expect(page).to have_link "Goals and Targets"
|
||||
end
|
||||
end
|
||||
|
||||
context "one process disabled" do
|
||||
before { Setting["process.debates"] = false }
|
||||
|
||||
it "generates links to the enabled processes" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_link "Goals and Targets"
|
||||
expect(page).to have_link "Participatory budgets"
|
||||
expect(page).to have_link "Collaborative legislation"
|
||||
expect(page).to have_link "Polls"
|
||||
expect(page).to have_link "Proposals"
|
||||
|
||||
expect(page).not_to have_link "Debates"
|
||||
end
|
||||
end
|
||||
|
||||
context "one SDG process disabled" do
|
||||
before { Setting["sdg.process.legislation"] = false }
|
||||
|
||||
it "generates links to the enabled processes" do
|
||||
render_inline component
|
||||
|
||||
expect(page).to have_link "Goals and Targets"
|
||||
expect(page).to have_link "Debates"
|
||||
expect(page).to have_link "Participatory budgets"
|
||||
expect(page).to have_link "Polls"
|
||||
expect(page).to have_link "Proposals"
|
||||
|
||||
expect(page).not_to have_link "Collaborative legislation"
|
||||
end
|
||||
end
|
||||
end
|
||||
98
spec/controllers/sdg_management/relations_spec.rb
Normal file
98
spec/controllers/sdg_management/relations_spec.rb
Normal file
@@ -0,0 +1,98 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe SDGManagement::RelationsController do
|
||||
before do
|
||||
sign_in create(:administrator).user
|
||||
|
||||
Setting["feature.sdg"] = true
|
||||
Setting["sdg.process.budgets"] = true
|
||||
Setting["sdg.process.debates"] = true
|
||||
Setting["sdg.process.legislation"] = true
|
||||
Setting["sdg.process.polls"] = true
|
||||
Setting["sdg.process.proposals"] = true
|
||||
end
|
||||
|
||||
context "processes disabled" do
|
||||
it "raises feature disabled for budgets" do
|
||||
Setting["process.budgets"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "budget/investments" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for debates" do
|
||||
Setting["process.debates"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "debates" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for legislation processes" do
|
||||
Setting["process.legislation"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "legislation/processes" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for polls" do
|
||||
Setting["process.polls"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "polls" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for proposals" do
|
||||
Setting["process.proposals"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "proposals" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
end
|
||||
|
||||
context "SDG processes disabled" do
|
||||
it "raises feature disabled for budgets" do
|
||||
Setting["sdg.process.budgets"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "budget/investments" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for debates" do
|
||||
Setting["sdg.process.debates"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "debates" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for legislation processes" do
|
||||
Setting["sdg.process.legislation"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "legislation/processes" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for polls" do
|
||||
Setting["sdg.process.polls"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "polls" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
|
||||
it "raises feature disabled for proposals" do
|
||||
Setting["sdg.process.proposals"] = false
|
||||
|
||||
expect do
|
||||
get :index, params: { relatable_type: "proposals" }
|
||||
end.to raise_exception(FeatureFlags::FeatureDisabled)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -32,3 +32,33 @@ describe "rake db:load_sdg" do
|
||||
expect(SDG::Target.last.id).to eq target_id
|
||||
end
|
||||
end
|
||||
|
||||
describe "rake db:calculate_tsv" do
|
||||
before { Rake::Task["db:calculate_tsv"].reenable }
|
||||
|
||||
let :run_rake_task do
|
||||
Rake.application.invoke_task("db:calculate_tsv")
|
||||
end
|
||||
|
||||
it "calculates the tsvector for polls" do
|
||||
poll = create(:poll)
|
||||
poll.update_column(:tsv, nil)
|
||||
|
||||
expect(poll.reload.tsv).to be nil
|
||||
|
||||
run_rake_task
|
||||
|
||||
expect(poll.reload.tsv).not_to be nil
|
||||
end
|
||||
|
||||
it "calculates the tsvector for legislation processes" do
|
||||
process = create(:legislation_process)
|
||||
process.update_column(:tsv, nil)
|
||||
|
||||
expect(process.reload.tsv).to be nil
|
||||
|
||||
run_rake_task
|
||||
|
||||
expect(process.reload.tsv).not_to be nil
|
||||
end
|
||||
end
|
||||
@@ -229,4 +229,35 @@ describe Legislation::Process do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".search" do
|
||||
let!(:traffic) do
|
||||
create(:legislation_process,
|
||||
title: "Traffic regulation",
|
||||
summary: "Lane structure",
|
||||
description: "From top to bottom")
|
||||
end
|
||||
|
||||
let!(:animal_farm) do
|
||||
create(:legislation_process,
|
||||
title: "Hierarchy structure",
|
||||
summary: "Pigs at the top",
|
||||
description: "Napoleon in charge of the traffic")
|
||||
end
|
||||
|
||||
it "returns only matching polls" do
|
||||
expect(Legislation::Process.search("lane")).to eq [traffic]
|
||||
expect(Legislation::Process.search("pigs")).to eq [animal_farm]
|
||||
expect(Legislation::Process.search("nothing here")).to be_empty
|
||||
end
|
||||
|
||||
it "gives more weight to name" do
|
||||
expect(Legislation::Process.search("traffic")).to eq [traffic, animal_farm]
|
||||
expect(Legislation::Process.search("structure")).to eq [animal_farm, traffic]
|
||||
end
|
||||
|
||||
it "gives more weight to summary than description" do
|
||||
expect(Legislation::Process.search("top")).to eq [animal_farm, traffic]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -433,4 +433,29 @@ describe Poll do
|
||||
expect(poll.recounts_confirmed?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe ".search" do
|
||||
let!(:square) do
|
||||
create(:poll, name: "Square reform", summary: "Next to the park", description: "Give it more space")
|
||||
end
|
||||
|
||||
let!(:park) do
|
||||
create(:poll, name: "New park", summary: "Green spaces", description: "Next to the square")
|
||||
end
|
||||
|
||||
it "returns only matching polls" do
|
||||
expect(Poll.search("reform")).to eq [square]
|
||||
expect(Poll.search("green")).to eq [park]
|
||||
expect(Poll.search("nothing here")).to be_empty
|
||||
end
|
||||
|
||||
it "gives more weight to name" do
|
||||
expect(Poll.search("square")).to eq [square, park]
|
||||
expect(Poll.search("park")).to eq [park, square]
|
||||
end
|
||||
|
||||
it "gives more weight to summary than description" do
|
||||
expect(Poll.search("space")).to eq [park, square]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -28,6 +28,14 @@ describe SDG::Relatable do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#sdg_goal_list" do
|
||||
it "orders goals by code" do
|
||||
relatable.sdg_goals = [SDG::Goal[1], SDG::Goal[3], SDG::Goal[2]]
|
||||
|
||||
expect(relatable.sdg_goal_list).to eq "1, 2, 3"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#sdg_targets" do
|
||||
it "can assign targets to a model" do
|
||||
relatable.sdg_targets = [target, another_target]
|
||||
@@ -46,6 +54,14 @@ describe SDG::Relatable do
|
||||
end
|
||||
end
|
||||
|
||||
describe "#sdg_target_list" do
|
||||
it "orders targets by code" do
|
||||
relatable.sdg_targets = [SDG::Target[2.2], SDG::Target[1.2], SDG::Target[2.1]]
|
||||
|
||||
expect(relatable.sdg_target_list).to eq "1.2, 2.1, 2.2"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#sdg_local_targets" do
|
||||
it "can assign local targets to a model" do
|
||||
relatable.sdg_local_targets = [local_target, another_local_target]
|
||||
@@ -74,4 +90,72 @@ describe SDG::Relatable do
|
||||
expect(relatable.reload.related_sdgs).to match_array related_sdgs
|
||||
end
|
||||
end
|
||||
|
||||
describe "#sdg_target_list=" do
|
||||
it "assigns a single target" do
|
||||
relatable.sdg_target_list = "1.1"
|
||||
|
||||
expect(relatable.reload.sdg_targets).to match_array [SDG::Target["1.1"]]
|
||||
end
|
||||
|
||||
it "assigns multiple targets" do
|
||||
relatable.sdg_target_list = "1.1,2.3"
|
||||
|
||||
expect(relatable.reload.sdg_targets).to match_array [SDG::Target["1.1"], SDG::Target["2.3"]]
|
||||
end
|
||||
|
||||
it "ignores trailing spaces and spaces between commas" do
|
||||
relatable.sdg_target_list = " 1.1, 2.3 "
|
||||
|
||||
expect(relatable.reload.sdg_targets).to match_array [SDG::Target["1.1"], SDG::Target["2.3"]]
|
||||
end
|
||||
|
||||
it "assigns goals" do
|
||||
relatable.sdg_target_list = "1.1,1.2,2.3"
|
||||
|
||||
expect(relatable.reload.sdg_goals).to match_array [SDG::Goal[1], SDG::Goal[2]]
|
||||
end
|
||||
end
|
||||
|
||||
describe ".by_goal" do
|
||||
it "returns everything if no code is provided" do
|
||||
expect(relatable.class.by_goal("")).to eq [relatable]
|
||||
expect(relatable.class.by_goal(nil)).to eq [relatable]
|
||||
end
|
||||
|
||||
it "returns records associated with that goal" do
|
||||
same_association = create(:proposal, sdg_goals: [goal])
|
||||
both_associations = create(:proposal, sdg_goals: [goal, another_goal])
|
||||
|
||||
expect(relatable.class.by_goal(goal.code)).to match_array [same_association, both_associations]
|
||||
end
|
||||
|
||||
it "does not return records not associated with that goal" do
|
||||
create(:proposal)
|
||||
create(:proposal, sdg_goals: [another_goal])
|
||||
|
||||
expect(relatable.class.by_goal(goal.code)).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe ".by_target" do
|
||||
it "returns everything if no code is provided" do
|
||||
expect(relatable.class.by_target("")).to eq [relatable]
|
||||
expect(relatable.class.by_target(nil)).to eq [relatable]
|
||||
end
|
||||
|
||||
it "returns records associated with that target" do
|
||||
same_association = create(:proposal, sdg_targets: [target])
|
||||
both_associations = create(:proposal, sdg_targets: [target, another_target])
|
||||
|
||||
expect(relatable.class.by_target(target.code)).to match_array [same_association, both_associations]
|
||||
end
|
||||
|
||||
it "does not return records not associated with that target" do
|
||||
create(:proposal)
|
||||
create(:proposal, sdg_targets: [another_target])
|
||||
|
||||
expect(relatable.class.by_target(target.code)).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
32
spec/routing/sdg_management_routes_spec.rb
Normal file
32
spec/routing/sdg_management_routes_spec.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "SDG Management routes" do
|
||||
it "maps routes for relatable classes" do
|
||||
expect(get("/sdg_management/proposals")).to route_to(
|
||||
controller: "sdg_management/relations",
|
||||
action: "index",
|
||||
relatable_type: "proposals"
|
||||
)
|
||||
end
|
||||
|
||||
it "admits named routes" do
|
||||
expect(get(sdg_management_polls_path)).to route_to(
|
||||
controller: "sdg_management/relations",
|
||||
action: "index",
|
||||
relatable_type: "polls"
|
||||
)
|
||||
end
|
||||
|
||||
it "routes relatable types containing a slash" do
|
||||
expect(url_for(
|
||||
controller: "sdg_management/relations",
|
||||
action: "index",
|
||||
relatable_type: "legislation/processes",
|
||||
only_path: true
|
||||
)).to eq "/sdg_management/legislation/processes"
|
||||
end
|
||||
|
||||
it "does not accept non-relatable classes" do
|
||||
expect(get("/sdg_management/tags")).not_to be_routable
|
||||
end
|
||||
end
|
||||
145
spec/system/sdg_management/relations_spec.rb
Normal file
145
spec/system/sdg_management/relations_spec.rb
Normal file
@@ -0,0 +1,145 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "SDG Relations", :js do
|
||||
before do
|
||||
login_as(create(:administrator).user)
|
||||
Setting["feature.sdg"] = true
|
||||
Setting["sdg.process.budgets"] = true
|
||||
Setting["sdg.process.debates"] = true
|
||||
Setting["sdg.process.legislation"] = true
|
||||
Setting["sdg.process.polls"] = true
|
||||
Setting["sdg.process.proposals"] = true
|
||||
end
|
||||
|
||||
scenario "navigation" do
|
||||
visit sdg_management_root_path
|
||||
|
||||
within("#side_menu") { click_link "Participatory budgets" }
|
||||
|
||||
expect(page).to have_current_path "/sdg_management/budget/investments"
|
||||
expect(page).to have_css "h2", exact_text: "Participatory budgets"
|
||||
|
||||
within("#side_menu") { click_link "Debates" }
|
||||
|
||||
expect(page).to have_current_path "/sdg_management/debates"
|
||||
expect(page).to have_css "h2", exact_text: "Debates"
|
||||
|
||||
within("#side_menu") { click_link "Collaborative legislation" }
|
||||
|
||||
expect(page).to have_current_path "/sdg_management/legislation/processes"
|
||||
expect(page).to have_css "h2", exact_text: "Collaborative legislation"
|
||||
|
||||
within("#side_menu") { click_link "Polls" }
|
||||
|
||||
expect(page).to have_current_path "/sdg_management/polls"
|
||||
expect(page).to have_css "h2", exact_text: "Polls"
|
||||
|
||||
within("#side_menu") { click_link "Proposals" }
|
||||
|
||||
expect(page).to have_current_path "/sdg_management/proposals"
|
||||
expect(page).to have_css "h2", exact_text: "Proposals"
|
||||
end
|
||||
|
||||
describe "Index" do
|
||||
scenario "list records for the current model" do
|
||||
create(:debate, title: "I'm a debate")
|
||||
create(:proposal, title: "And I'm a proposal")
|
||||
|
||||
visit sdg_management_debates_path
|
||||
|
||||
expect(page).to have_text "I'm a debate"
|
||||
expect(page).not_to have_text "I'm a proposal"
|
||||
|
||||
visit sdg_management_proposals_path
|
||||
|
||||
expect(page).to have_text "I'm a proposal"
|
||||
expect(page).not_to have_text "I'm a debate"
|
||||
end
|
||||
|
||||
scenario "list goals and target for all records" do
|
||||
redistribute = create(:proposal, title: "Resources distribution")
|
||||
redistribute.sdg_goals = [SDG::Goal[1]]
|
||||
redistribute.sdg_targets = [SDG::Target["1.1"]]
|
||||
|
||||
treatment = create(:proposal, title: "Treatment system")
|
||||
treatment.sdg_goals = [SDG::Goal[6]]
|
||||
treatment.sdg_targets = [SDG::Target["6.1"], SDG::Target["6.2"]]
|
||||
|
||||
visit sdg_management_proposals_path
|
||||
|
||||
within("tr", text: "Resources distribution") do
|
||||
expect(page).to have_content "1.1"
|
||||
end
|
||||
|
||||
within("tr", text: "Treatment system") do
|
||||
expect(page).to have_content "6.1, 6.2"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "shows link to edit a record" do
|
||||
create(:budget_investment, title: "Build a hospital")
|
||||
|
||||
visit sdg_management_budget_investments_path
|
||||
|
||||
within("tr", text: "Build a hospital") do
|
||||
click_link "Manage goals and targets"
|
||||
end
|
||||
|
||||
expect(page).to have_css "h2", exact_text: "Build a hospital"
|
||||
end
|
||||
|
||||
describe "search" do
|
||||
scenario "search by terms" do
|
||||
create(:poll, name: "Internet speech freedom")
|
||||
create(:poll, name: "SDG interest")
|
||||
|
||||
visit sdg_management_polls_path
|
||||
|
||||
fill_in "search", with: "speech"
|
||||
click_button "Search"
|
||||
|
||||
expect(page).to have_content "Internet speech freedom"
|
||||
expect(page).not_to have_content "SDG interest"
|
||||
end
|
||||
|
||||
scenario "goal filter" do
|
||||
create(:budget_investment, title: "School", sdg_goals: [SDG::Goal[4]])
|
||||
create(:budget_investment, title: "Hospital", sdg_goals: [SDG::Goal[3]])
|
||||
|
||||
visit sdg_management_budget_investments_path
|
||||
select "4. Quality Education", from: "goal_code"
|
||||
click_button "Search"
|
||||
|
||||
expect(page).to have_content "School"
|
||||
expect(page).not_to have_content "Hospital"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "target filter" do
|
||||
create(:budget_investment, title: "School", sdg_targets: [SDG::Target[4.1]])
|
||||
create(:budget_investment, title: "Preschool", sdg_targets: [SDG::Target[4.2]])
|
||||
|
||||
visit sdg_management_budget_investments_path
|
||||
select "4.1", from: "target_code"
|
||||
click_button "Search"
|
||||
|
||||
expect(page).to have_content "School"
|
||||
expect(page).not_to have_content "Preschool"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Edit" do
|
||||
scenario "allows changing the targets" do
|
||||
process = create(:legislation_process, title: "SDG process")
|
||||
process.sdg_targets = [SDG::Target["3.3"]]
|
||||
|
||||
visit sdg_management_edit_legislation_process_path(process)
|
||||
fill_in "Targets", with: "1.2, 2.1"
|
||||
click_button "Update Process"
|
||||
|
||||
within("tr", text: "SDG process") do
|
||||
expect(page).to have_css "td", exact_text: "1.2, 2.1"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user