Merge branch 'master' into remove_investments_internal_comments

This commit is contained in:
BertoCQ
2018-01-31 13:47:15 +01:00
committed by GitHub
94 changed files with 1213 additions and 697 deletions

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 284 KiB

After

Width:  |  Height:  |  Size: 284 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1641,7 +1641,7 @@ table {
// 13. Pages // 13. Pages
// --------- // ---------
.more-information { .help {
li { li {
border-bottom: 1px solid $border; border-bottom: 1px solid $border;

View File

@@ -61,12 +61,13 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
end end
def load_investments def load_investments
if params[:project_title].present? @investments = if params[:project_title].present?
@investments = Budget::Investment.where("title ILIKE ?", "%#{params[:project_title].strip}%") Budget::Investment.where("title ILIKE ?",
else "%#{params[:project_title].strip}%")
@investments = Budget::Investment.scoped_filter(params, @current_filter) else
Budget::Investment.scoped_filter(params, @current_filter)
.order(sort_by(params[:sort_by])) .order(sort_by(params[:sort_by]))
end end
@investments = @investments.page(params[:page]) unless request.format.csv? @investments = @investments.page(params[:page]) unless request.format.csv?
end end

View File

@@ -14,8 +14,7 @@ class BudgetsController < ApplicationController
end end
def index def index
@budgets = @budgets.order(created_at: :desc) @finished_budgets = @budgets.finished.order(created_at: :desc)
@budget = current_budget
@budgets_coordinates = current_budget_map_locations @budgets_coordinates = current_budget_map_locations
end end

View File

@@ -45,12 +45,13 @@ class CommentsController < ApplicationController
def comment_params def comment_params
params.require(:comment).permit(:commentable_type, :commentable_id, :parent_id, params.require(:comment).permit(:commentable_type, :commentable_id, :parent_id,
:body, :as_moderator, :as_administrator) :body, :as_moderator, :as_administrator, :valuation)
end end
def build_comment def build_comment
@comment = Comment.build(@commentable, current_user, comment_params[:body], @comment = Comment.build(@commentable, current_user, comment_params[:body],
comment_params[:parent_id].presence) comment_params[:parent_id].presence,
comment_params[:valuation])
check_for_special_comments check_for_special_comments
end end

View File

@@ -1,11 +1,14 @@
class Valuation::BudgetInvestmentsController < Valuation::BaseController class Valuation::BudgetInvestmentsController < Valuation::BaseController
include FeatureFlags include FeatureFlags
include CommentableActions
feature_flag :budgets feature_flag :budgets
before_action :restrict_access_to_assigned_items, only: [:show, :edit, :valuate] before_action :restrict_access_to_assigned_items, only: [:show, :edit, :valuate]
before_action :load_budget before_action :load_budget
before_action :load_investment, only: [:show, :edit, :valuate] before_action :load_investment, only: [:show, :edit, :valuate]
has_orders %w{oldest}, only: [:show, :edit]
has_filters %w{valuating valuation_finished}, only: :index has_filters %w{valuating valuation_finished}, only: :index
load_and_authorize_resource :investment, class: "Budget::Investment" load_and_authorize_resource :investment, class: "Budget::Investment"
@@ -36,8 +39,30 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController
end end
end end
def show
load_comments
end
def edit
load_comments
end
private private
def load_comments
@commentable = @investment
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order, valuations: true)
set_comment_flags(@comment_tree.comments)
end
def resource_model
Budget::Investment
end
def resource_name
resource_model.parameterize('_')
end
def load_budget def load_budget
@budget = Budget.find(params[:budget_id]) @budget = Budget.find(params[:budget_id])
end end

View File

@@ -55,7 +55,7 @@ module Abilities
can [:read, :create, :update, :destroy], Budget::Group can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :update, :toggle_selection], Budget::Investment can [:hide, :update, :toggle_selection], Budget::Investment
can :valuate, Budget::Investment can [:valuate, :comment_valuation], Budget::Investment
can :create, Budget::ValuatorAssignment can :create, Budget::ValuatorAssignment
can [:search, :edit, :update, :create, :index, :destroy], Banner can [:search, :edit, :update, :create, :index, :destroy], Banner

View File

@@ -5,8 +5,8 @@ module Abilities
def initialize(user) def initialize(user)
valuator = user.valuator valuator = user.valuator
can [:read, :update, :valuate], SpendingProposal can [:read, :update, :valuate], SpendingProposal
can [:read, :update, :valuate], Budget::Investment, id: valuator.investment_ids can [:read, :update, :valuate, :comment_valuation], Budget::Investment, id: valuator.investment_ids
cannot [:update, :valuate], Budget::Investment, budget: { phase: 'finished' } cannot [:update, :valuate, :comment_valuation], Budget::Investment, budget: { phase: 'finished' }
end end
end end
end end

View File

@@ -10,5 +10,8 @@ class Budget
validates :name, presence: true, uniqueness: { scope: :budget } validates :name, presence: true, uniqueness: { scope: :budget }
validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/ validates :slug, presence: true, format: /\A[a-z0-9\-_]+\z/
def single_heading_group?
headings.count == 1
end
end end
end end

View File

@@ -17,7 +17,7 @@ class Budget
scope :order_by_group_name, -> { includes(:group).order('budget_groups.name', 'budget_headings.name') } scope :order_by_group_name, -> { includes(:group).order('budget_groups.name', 'budget_headings.name') }
def name_scoped_by_group def name_scoped_by_group
"#{group.name}: #{name}" group.single_heading_group? ? name : "#{group.name}: #{name}"
end end
def name_exists_in_budget_headings def name_exists_in_budget_headings

View File

@@ -34,7 +34,10 @@ class Budget
has_many :valuator_assignments, dependent: :destroy has_many :valuator_assignments, dependent: :destroy
has_many :valuators, through: :valuator_assignments has_many :valuators, through: :valuator_assignments
has_many :comments, as: :commentable
has_many :comments, -> {where(valuation: false)}, as: :commentable, class_name: 'Comment'
has_many :valuations, -> {where(valuation: true)}, as: :commentable, class_name: 'Comment'
has_many :milestones has_many :milestones
validates :title, presence: true validates :title, presence: true
@@ -86,6 +89,10 @@ class Budget
before_validation :set_responsible_name before_validation :set_responsible_name
before_validation :set_denormalized_ids before_validation :set_denormalized_ids
def comments_count
comments.count
end
def url def url
budget_investment_path(budget, self) budget_investment_path(budget, self)
end end

View File

@@ -20,6 +20,7 @@ class Comment < ActiveRecord::Base
validates :commentable_type, inclusion: { in: COMMENTABLE_TYPES } validates :commentable_type, inclusion: { in: COMMENTABLE_TYPES }
validate :validate_body_length validate :validate_body_length
validate :comment_valuation, if: -> { valuation }
belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true
belongs_to :user, -> { with_hidden } belongs_to :user, -> { with_hidden }
@@ -33,7 +34,8 @@ class Comment < ActiveRecord::Base
end end
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) } scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
scope :public_for_api, -> do scope :public_for_api, -> do
where(%{(comments.commentable_type = 'Debate' and comments.commentable_id in (?)) or not_valuations
.where(%{(comments.commentable_type = 'Debate' and comments.commentable_id in (?)) or
(comments.commentable_type = 'Proposal' and comments.commentable_id in (?)) or (comments.commentable_type = 'Proposal' and comments.commentable_id in (?)) or
(comments.commentable_type = 'Poll' and comments.commentable_id in (?))}, (comments.commentable_type = 'Poll' and comments.commentable_id in (?))},
Debate.public_for_api.pluck(:id), Debate.public_for_api.pluck(:id),
@@ -50,13 +52,16 @@ class Comment < ActiveRecord::Base
scope :sort_by_oldest, -> { order(created_at: :asc) } scope :sort_by_oldest, -> { order(created_at: :asc) }
scope :sort_descendants_by_oldest, -> { order(created_at: :asc) } scope :sort_descendants_by_oldest, -> { order(created_at: :asc) }
scope :not_valuations, -> { where(valuation: false) }
after_create :call_after_commented after_create :call_after_commented
def self.build(commentable, user, body, p_id = nil) def self.build(commentable, user, body, p_id = nil, valuation = false)
new commentable: commentable, new(commentable: commentable,
user_id: user.id, user_id: user.id,
body: body, body: body,
parent_id: p_id parent_id: p_id,
valuation: valuation)
end end
def self.find_commentable(c_type, c_id) def self.find_commentable(c_type, c_id)
@@ -129,4 +134,9 @@ class Comment < ActiveRecord::Base
validator.validate(self) validator.validate(self)
end end
def comment_valuation
unless author.can?(:comment_valuation, commentable)
errors.add(:valuation, :cannot_comment_valuation)
end
end
end end

View File

@@ -27,15 +27,14 @@
class: "js-submit-on-change" } %> class: "js-submit-on-change" } %>
</div> </div>
<div class="small-12 medium-3 column"> <div class="small-12 medium-3 column">
<%= select_tag :tag_name, <%= select_tag :tag_name,
options_for_select(investment_tags_select_options(@budget), params[:tag_name]), options_for_select(investment_tags_select_options(@budget), params[:tag_name]),
{ prompt: t("admin.budget_investments.index.tags_filter_all"), { prompt: t("admin.budget_investments.index.tags_filter_all"),
label: false, label: false,
class: "js-submit-on-change" } %> class: "js-submit-on-change" } %>
</div> </div>
<% end %> <% end %>
</div>
<%= render "advanced_filters", i18n_namespace: "admin.budget_investments.index" %> <%= render "advanced_filters", i18n_namespace: "admin.budget_investments.index" %>

View File

@@ -20,8 +20,8 @@
<% else %> <% else %>
<tr> <tr>
<th><%= t("admin.budgets.form.table_heading") %></th> <th><%= t("admin.budgets.form.table_heading") %></th>
<th><%= t("admin.budgets.form.table_amount") %></th> <th class="text-right"><%= t("admin.budgets.form.table_amount") %></th>
<th><%= t("admin.budgets.form.table_population") %></th> <th class="text-right"><%= t("admin.budgets.form.table_population") %></th>
<th><%= t("admin.actions.actions") %></th> <th><%= t("admin.actions.actions") %></th>
</tr> </tr>
</thead> </thead>

View File

@@ -2,10 +2,10 @@
<td> <td>
<%= heading.name %> <%= heading.name %>
</td> </td>
<td> <td class="text-right">
<%= heading.price %> <%= heading.budget.formatted_heading_price(heading) %>
</td> </td>
<td> <td class="text-right">
<%= heading.population %> <%= heading.population %>
</td> </td>
<td> <td>

View File

@@ -1,6 +1,6 @@
<ul class="no-bullet budget-timeline"> <ul class="no-bullet budget-timeline">
<% @budget.published_phases.each do |phase| %> <% current_budget.published_phases.each do |phase| %>
<li class="phase <%= 'active' if phase == @budget.current_phase %>"> <li class="phase <%= 'active' if phase == current_budget.current_phase %>">
<h3><%= t("budgets.phase.#{phase.kind}") %></h3> <h3><%= t("budgets.phase.#{phase.kind}") %></h3>
<span> <span>
<%= l(phase.starts_at.to_date, format: :long) if phase.starts_at.present? %> <%= l(phase.starts_at.to_date, format: :long) if phase.starts_at.present? %>

View File

@@ -7,9 +7,9 @@
<div class="row" data-equalizer data-equalizer-on="medium"> <div class="row" data-equalizer data-equalizer-on="medium">
<div class="small-12 medium-9 column padding" data-equalizer-watch> <div class="small-12 medium-9 column padding" data-equalizer-watch>
<h1><%= @budget.name %></h1> <h1><%= current_budget.name %></h1>
<div class="description"> <div class="description">
<%= safe_html_with_links(@budget.description) %> <%= safe_html_with_links(current_budget.description) %>
</div> </div>
<p> <p>
<%= link_to t("budgets.index.section_header.help"), "#section_help" %> <%= link_to t("budgets.index.section_header.help"), "#section_help" %>
@@ -19,11 +19,11 @@
<p> <p>
<strong><%= t('budgets.show.phase') %></strong> <strong><%= t('budgets.show.phase') %></strong>
</p> </p>
<h2><%= t("budgets.phase.#{@budget.phase}") %></h2> <h2><%= t("budgets.phase.#{current_budget.phase}") %></h2>
<%= link_to t("budgets.index.section_header.all_phases"), "#all_phases" %> <%= link_to t("budgets.index.section_header.all_phases"), "#all_phases" %>
<% if @budget.accepting? %> <% if current_budget.accepting? %>
<% if current_user %> <% if current_user %>
<% if current_user.level_two_or_three_verified? %> <% if current_user.level_two_or_three_verified? %>
<%= link_to t("budgets.investments.index.sidebar.create"), <%= link_to t("budgets.investments.index.sidebar.create"),
@@ -48,9 +48,9 @@
<% end %> <% end %>
<% if @budget.finished? || (@budget.balloting? && can?(:read_results, @budget)) %> <% if current_budget.finished? || (current_budget.balloting? && can?(:read_results, current_budget)) %>
<%= link_to t("budgets.show.see_results"), <%= link_to t("budgets.show.see_results"),
budget_results_path(@budget, heading_id: @budget.headings.first), budget_results_path(current_budget, heading_id: current_budget.headings.first),
class: "button margin-top expanded" %> class: "button margin-top expanded" %>
<% end %> <% end %>
</div> </div>
@@ -62,18 +62,18 @@
<div class="small-12 column"> <div class="small-12 column">
<div id="groups_and_headings" class="groups-and-headings"> <div id="groups_and_headings" class="groups-and-headings">
<% @budget.groups.each do |group| %> <% current_budget.groups.each do |group| %>
<h2><%= group.name %></h2> <h2><%= group.name %></h2>
<ul class="no-bullet"> <ul class="no-bullet">
<% group.headings.order_by_group_name.each do |heading| %> <% group.headings.order_by_group_name.each do |heading| %>
<li class="heading small-12 medium-4 large-2"> <li class="heading small-12 medium-4 large-2">
<% unless @budget.informing? %> <% unless current_budget.informing? %>
<%= link_to budget_investments_path(@budget.id, heading_id: heading.id) do %> <%= link_to budget_investments_path(current_budget.id, heading_id: heading.id) do %>
<%= heading_name_and_price_html(heading, @budget) %> <%= heading_name_and_price_html(heading, current_budget) %>
<% end %> <% end %>
<% else %> <% else %>
<div> <div>
<%= heading_name_and_price_html(heading, @budget) %> <%= heading_name_and_price_html(heading, current_budget) %>
</div> </div>
<% end %> <% end %>
</li> </li>
@@ -82,20 +82,20 @@
<% end %> <% end %>
</div> </div>
<% unless @budget.informing? %> <% unless current_budget.informing? %>
<div id="map"> <div id="map">
<h3><%= t("budgets.index.map") %></h3> <h3><%= t("budgets.index.map") %></h3>
<%= render_map(nil, "budgets", false, nil, @budgets_coordinates) %> <%= render_map(nil, "budgets", false, nil, @budgets_coordinates) %>
</div> </div>
<p> <p>
<%= link_to budget_investments_path(@budget.id) do %> <%= link_to budget_investments_path(current_budget.id) do %>
<small><%= t("budgets.index.investment_proyects") %></small> <small><%= t("budgets.index.investment_proyects") %></small>
<% end %><br> <% end %><br>
<%= link_to budget_investments_path(budget_id: @budget.id, filter: 'unfeasible') do %> <%= link_to budget_investments_path(budget_id: current_budget.id, filter: 'unfeasible') do %>
<small><%= t("budgets.index.unfeasible_investment_proyects") %></small> <small><%= t("budgets.index.unfeasible_investment_proyects") %></small>
<% end %><br> <% end %><br>
<%= link_to budget_investments_path(budget_id: @budget.id, filter: 'unselected') do %> <%= link_to budget_investments_path(budget_id: current_budget.id, filter: 'unselected') do %>
<small><%= t("budgets.index.not_selected_investment_proyects") %></small> <small><%= t("budgets.index.not_selected_investment_proyects") %></small>
<% end %> <% end %>
</p> </p>
@@ -103,26 +103,26 @@
<div id="all_phases"> <div id="all_phases">
<h2><%= t("budgets.index.all_phases") %></h2> <h2><%= t("budgets.index.all_phases") %></h2>
<%= render "phases" %> <%= render "phases", budget: current_budget %>
</div> </div>
</div> </div>
</div> </div>
<div class="row margin-top"> <% if @finished_budgets.present? %>
<div class="small-12 medium-9 column"> <div class="row margin-top">
<ul class="no-bullet submenu"> <div class="small-12 medium-9 column">
<li class="inline-block"> <ul class="no-bullet submenu">
<%= link_to "#other_budgets", class: "active" do %> <li class="inline-block">
<h2> <%= link_to "#other_budgets", class: "active" do %>
<%= t("budgets.index.finished_budgets") %> <h2>
</h2> <%= t("budgets.index.finished_budgets") %>
<% end %> </h2>
</li> <% end %>
</ul> </li>
</ul>
<div class="budget-investments-list"> <div id="finished_budgets" class="budget-investments-list">
<% @budgets.each do |budget| %> <% @finished_budgets.each do |budget| %>
<% if budget_published?(budget) %>
<div class="budget-investment clear"> <div class="budget-investment clear">
<div class="panel past-budgets"> <div class="panel past-budgets">
<div class="row" data-equalizer data-equalizer-on="medium"> <div class="row" data-equalizer data-equalizer-on="medium">
@@ -142,10 +142,10 @@
</div> </div>
</div> </div>
<% end %> <% end %>
<% end %> </div>
</div> </div>
</div> </div>
</div> <% end %>
<div class="row"> <div class="row">
<div class="small-12 column"> <div class="small-12 column">

View File

@@ -60,7 +60,7 @@
<% @budget.groups.each do |group| %> <% @budget.groups.each do |group| %>
<tr> <tr>
<td> <td>
<% if group.headings.count == 1 %> <% if group.single_heading_group? %>
<%= link_to group.name, <%= link_to group.name,
budget_investments_path(@budget, budget_investments_path(@budget,
heading_id: group.headings.first.id, heading_id: group.headings.first.id,

View File

@@ -1,6 +1,8 @@
<span id="flag-actions-<%= dom_id(comment) %>" class="js-flag-actions"> <% if local_assigns.fetch(:allow_flagging, true) %>
<%= render 'comments/flag_actions', comment: comment %> <span id="flag-actions-<%= dom_id(comment) %>" class="js-flag-actions">
</span> <%= render 'comments/flag_actions', comment: comment %>
</span>
<% end %>
<span class='js-moderation-actions'> <span class='js-moderation-actions'>
<% if can? :hide, comment %> <% if can? :hide, comment %>

View File

@@ -1,4 +1,7 @@
<% comment_flags ||= @comment_flags %> <% comment_flags ||= @comment_flags %>
<% valuation = local_assigns.fetch(:valuation, false) %>
<% allow_votes = local_assigns.fetch(:allow_votes, true) %>
<% allow_flagging = local_assigns.fetch(:allow_flagging, true) %>
<% cache [locale_and_user_status(comment), comment, commentable_cache_key(comment.commentable), comment.author, (comment_flags[comment.id] if comment_flags)] do %> <% cache [locale_and_user_status(comment), comment, commentable_cache_key(comment.commentable), comment.author, (comment_flags[comment.id] if comment_flags)] do %>
<ul id="<%= dom_id(comment) %>" class="comment no-bullet small-12"> <ul id="<%= dom_id(comment) %>" class="comment no-bullet small-12">
<li class="comment-body"> <li class="comment-body">
@@ -67,9 +70,11 @@
</div> </div>
<div id="<%= dom_id(comment) %>_reply" class="reply"> <div id="<%= dom_id(comment) %>_reply" class="reply">
<div id="<%= dom_id(comment) %>_votes" class="comment-votes float-right"> <% if allow_votes %>
<%= render 'comments/votes', comment: comment %> <div id="<%= dom_id(comment) %>_votes" class="comment-votes float-right">
</div> <%= render 'comments/votes', comment: comment %>
</div>
<% end %>
<% if comment.children.size > 0 %> <% if comment.children.size > 0 %>
<%= link_to "", class: "js-toggle-children relative", data: {'id': "#{dom_id(comment)}"} do %> <%= link_to "", class: "js-toggle-children relative", data: {'id': "#{dom_id(comment)}"} do %>
@@ -86,9 +91,13 @@
<%= link_to(comment_link_text(comment), "", <%= link_to(comment_link_text(comment), "",
class: "js-add-comment-link", data: {'id': dom_id(comment)}) %> class: "js-add-comment-link", data: {'id': dom_id(comment)}) %>
<%= render 'comments/actions', comment: comment %> <%= render 'comments/actions', { comment: comment,
allow_flagging: allow_flagging } %>
<%= render 'comments/form', {commentable: comment.commentable, parent_id: comment.id, toggeable: true} %> <%= render 'comments/form', {commentable: comment.commentable,
parent_id: comment.id,
toggeable: true,
valuation: valuation } %>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
@@ -98,7 +107,10 @@
<ul id="<%= dom_id(comment) %>_children" class="no-bullet comment-children"> <ul id="<%= dom_id(comment) %>_children" class="no-bullet comment-children">
<% child_comments_of(comment).each do |child| %> <% child_comments_of(comment).each do |child| %>
<li> <li>
<%= render 'comments/comment', comment: child %> <%= render 'comments/comment', { comment: child,
valuation: valuation,
allow_votes: allow_votes,
allow_flagging: allow_flagging } %>
</li> </li>
<% end %> <% end %>
</ul> </ul>

View File

@@ -1,5 +1,5 @@
<% commentable = comment_tree.commentable %> <% commentable = comment_tree.commentable %>
<% valuation = local_assigns.fetch(:valuation, false) %>
<% cache [locale_and_user_status, comment_tree.order, commentable_cache_key(commentable), comment_tree.comments, comment_tree.comment_authors, commentable.comments_count, comment_flags] do %> <% cache [locale_and_user_status, comment_tree.order, commentable_cache_key(commentable), comment_tree.comments, comment_tree.comment_authors, commentable.comments_count, comment_flags] do %>
<section class="expanded comments"> <section class="expanded comments">
<div class="row"> <div class="row">
@@ -27,7 +27,8 @@
<% else %> <% else %>
<%= render 'comments/form', { commentable: commentable, <%= render 'comments/form', { commentable: commentable,
parent_id: nil, parent_id: nil,
toggeable: false } %> toggeable: false,
valuation: valuation } %>
<% end %> <% end %>
<% else %> <% else %>
<br> <br>
@@ -39,7 +40,11 @@
<% end %> <% end %>
<% comment_tree.root_comments.each do |comment| %> <% comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', {comment: comment, comment_flags: comment_flags} %> <%= render 'comments/comment', { comment: comment,
comment_flags: comment_flags,
valuation: valuation,
allow_votes: !valuation,
allow_flagging: !valuation } %>
<% end %> <% end %>
<%= paginate comment_tree.root_comments %> <%= paginate comment_tree.root_comments %>
</div> </div>

View File

@@ -10,7 +10,10 @@
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %> <%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<% if user_signed_in? %> <% if user_signed_in? %>
<%= render 'comments/form', {commentable: @investment, parent_id: nil, toggeable: false} %> <%= render 'comments/form', { commentable: @investment,
parent_id: nil,
toggeable: false,
valuation: local_assigns.fetch(:valuation, false) } %>
<% else %> <% else %>
<br> <br>
@@ -22,7 +25,8 @@
<% end %> <% end %>
<% @comment_tree.root_comments.each do |comment| %> <% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %> <%= render 'comments/comment', { comment: comment,
valuation: local_assigns.fetch(:valuation, false) } %>
<% end %> <% end %>
<%= paginate @comment_tree.root_comments %> <%= paginate @comment_tree.root_comments %>
</div> </div>

View File

@@ -7,6 +7,7 @@
<%= f.hidden_field :commentable_type, value: commentable.class.name %> <%= f.hidden_field :commentable_type, value: commentable.class.name %>
<%= f.hidden_field :commentable_id, value: commentable.id %> <%= f.hidden_field :commentable_id, value: commentable.id %>
<%= f.hidden_field :parent_id, value: parent_id %> <%= f.hidden_field :parent_id, value: parent_id %>
<%= f.hidden_field :valuation, value: local_assigns.fetch(:valuation, false) %>
<%= f.submit comment_button_text(parent_id, commentable), class: "button", id: "publish_comment" %> <%= f.submit comment_button_text(parent_id, commentable), class: "button", id: "publish_comment" %>

View File

@@ -7,7 +7,7 @@
<div data-alert class="callout primary"> <div data-alert class="callout primary">
<%= t("debates.new.info", <%= t("debates.new.info",
info_link: link_to(t("debates.new.info_link"), new_proposal_path )).html_safe %> info_link: link_to(t("debates.new.info_link"), new_proposal_path )).html_safe %>
<%= link_to more_info_path, title: t('shared.target_blank_html'), target: "_blank" do %> <%= link_to help_path, title: t('shared.target_blank_html'), target: "_blank" do %>
<strong><%= t("debates.new.more_info") %></strong> <strong><%= t("debates.new.more_info") %></strong>
<% end %> <% end %>
</div> </div>

View File

@@ -5,7 +5,7 @@
<h1><%= t("proposals.new.start_new") %></h1> <h1><%= t("proposals.new.start_new") %></h1>
<div data-alert class="callout primary"> <div data-alert class="callout primary">
<%= link_to more_info_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %> <%= link_to help_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %>
<%= t("proposals.new.more_info")%> <%= t("proposals.new.more_info")%>
<% end %> <% end %>
</div> </div>

View File

@@ -0,0 +1,28 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="budgets" data-magellan-target="budgets">
<%= t("pages.help.budgets.title") %>
</h3>
<p>
<%= t("pages.help.budgets.description",
link: link_to(t("pages.help.budgets.link"), budgets_path)).html_safe %>
</p>
<ul class="features">
<li>
<%= t("pages.help.budgets.feature") %>
</li>
<li><%= t("pages.help.budgets.phase_1_html",
org: setting['org_name']).html_safe %></li>
<li><%= t("pages.help.budgets.phase_2_html") %></li>
<li><%= t("pages.help.budgets.phase_3_html") %></li>
<li><%= t("pages.help.budgets.phase_4_html") %></li>
</ul>
<p><%= t("pages.help.budgets.phase_5_html") %></p>
<figure>
<%= image_tag "help/budgets_#{I18n.locale}.png", alt: t("pages.help.budgets.image_alt") %>
<figcaption><%= t("pages.help.budgets.figcaption_html") %></figcaption>
</figure>
</div>
</div>

View File

@@ -0,0 +1,25 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="debates" data-magellan-target="debates">
<%= t("pages.help.debates.title") %>
</h3>
<p>
<%= t("pages.help.debates.description",
org: setting['org_name'],
link: link_to(t("pages.help.debates.link"),
debates_path)).html_safe %>
</p>
<ul class="features">
<li>
<%= t("pages.help.debates.feature_html",
link: link_to(t("pages.help.debates.feature_link", org: setting['org_name']),
new_user_registration_path)).html_safe %>
</li>
</ul>
<figure>
<%= image_tag "help/debates.png", alt: t("pages.help.debates.image_alt") %>
<figcaption><%= t("pages.help.debates.figcaption") %></figcaption>
</figure>
</div>
</div>

View File

@@ -0,0 +1,24 @@
<div class="row">
<div class="small-12 column">
<ul class="menu-pages" data-magellan>
<% if feature?(:debates) %>
<li>
<%= link_to t("pages.help.menu.debates"), "#debates", class: "button hollow expanded" %>
</li>
<% end %>
<% if feature?(:proposals) %>
<li>
<%= link_to t("pages.help.menu.proposals"), "#proposals", class: "button hollow expanded" %>
</li>
<% end %>
<% if feature?(:budgets) %>
<li>
<%= link_to t("pages.help.menu.budgets"), "#budgets", class: "button hollow expanded" %>
</li>
<% end %>
<li>
<%= link_to t("pages.help.menu.other"), "#other", class: "button hollow expanded" %>
</li>
</ul>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<h3 id="other" data-magellan-target="other"><%= t("pages.more_info.other.title") %></h3> <h3 id="other" data-magellan-target="other"><%= t("pages.help.other.title") %></h3>
<ul class="features"> <ul class="features">
<li><%= link_to t("pages.more_info.other.how_to_use", org_name: setting['org_name']), how_to_use_path %></li> <li><%= link_to t("pages.help.other.how_to_use", org_name: setting['org_name']), how_to_use_path %></li>
<% SiteCustomization::Page.with_more_info_flag.with_same_locale.each do |custom_page| %> <% SiteCustomization::Page.with_more_info_flag.with_same_locale.each do |custom_page| %>
<li><%= link_to custom_page.title, page_path(custom_page.slug) %></li> <li><%= link_to custom_page.title, page_path(custom_page.slug) %></li>

View File

@@ -0,0 +1,18 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="polls" data-magellan-target="polls"><%= t("pages.help.polls.title") %></h3>
<p>
<%= t("pages.help.polls.description",
link: link_to(t("pages.help.polls.link"), polls_path)).html_safe %>
</p>
<ul class="features">
<li>
<%= t("pages.help.polls.feature_1",
link: link_to(t("pages.help.polls.feature_1_link", org_name: setting['org_name']),
new_user_registration_path)).html_safe %>
</li>
<li><%= t("pages.help.polls.feature_2") %></li>
<li><%= t("pages.help.polls.feature_3") %></li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,23 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="proposals" data-magellan-target="proposals">
<%= t("pages.help.proposals.title") %>
</h3>
<p>
<%= t("pages.help.proposals.description",
link: link_to(t("pages.help.proposals.link"), proposals_path)).html_safe %>
</p>
<ul class="features">
<li>
<%= t("pages.help.proposals.feature_html",
org: setting['org_name'],
supports: setting['votes_for_proposal_success']).html_safe %>
</li>
</ul>
<figure>
<%= image_tag "help/proposals_#{I18n.locale}.png", alt: t("pages.help.proposals.image_alt") %>
<figcaption><%= t("pages.help.proposals.figcaption_html") %></figcaption>
</figure>
</div>
</div>

View File

@@ -0,0 +1,5 @@
<div class="sidebar-card">
<h3><%= t("pages.help.faq.title") %></h3>
<p><%= t("pages.help.faq.description") %></p>
<%= link_to t("pages.help.faq.button"), faq_path, class: "button expanded" %>
</div>

View File

@@ -0,0 +1,21 @@
<% content_for :canonical do %>
<%= render "shared/canonical", href: faq_url %>
<% end %>
<div class="row margin-top">
<div class="menu small-12 medium-3 column">
<%= back_link_to %>
<ul class="menu vertical margin-top">
<li><a href="#1"><strong><%= t("pages.help.faq.page.faq_1_title") %></strong></a></li>
</ul>
</div>
<div class="text small-12 medium-9 column">
<h1 class="clear"><%= t("pages.help.faq.page.title") %></h1>
<p><%= t("pages.help.faq.page.description") %></p>
<h2 id="1"><%= t("pages.help.faq.page.faq_1_title") %></h2>
<p><%= t("pages.help.faq.page.faq_1_description") %></p>
</div>
</div>

View File

@@ -6,8 +6,8 @@
<div class="text small-12 column"> <div class="text small-12 column">
<%= back_link_to %> <%= back_link_to %>
<h1><%= t('pages.more_info.titles.how_to_use') %></h1> <h1><%= t('pages.help.titles.how_to_use') %></h1>
<%= markdown t('pages.more_info.how_to_use.text') %> <%= markdown t('pages.help.how_to_use.text') %>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,48 @@
<% provide :title do %><%= t("pages.titles.help", org: setting['org_name']) %><% end %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: help_url %>
<% end %>
<div class="jumbo light">
<div class="row">
<div class="small-12 medium-9 column">
<h2><%= t("pages.help.title", org: setting['org_name']) %></h2>
<p><%= t("pages.help.subtitle", org: setting['org_name']) %></p>
<p><%= t("pages.help.guide", org: setting['org_name']) %></p>
</div>
</div>
<%= render "pages/help/menu" %>
</div>
<div id="more-info" class="more-info-content">
<div class="row">
<div class="small-12 medium-7 large-8 column">
<% if feature?(:debates) %>
<%= render "pages/help/debates" %>
<% end %>
<% if feature?(:proposals) %>
<%= render "pages/help/proposals" %>
<% end %>
<% if feature?(:budgets) %>
<%= render "pages/help/budgets" %>
<% end %>
<% if feature?(:polls) %>
<%= render "pages/help/polls" %>
<% end %>
</div>
<div class="small-12 medium-4 large-3 column more-info-sidebar">
<%= render "pages/help/sidebar" %>
</div>
</div>
<div class="row">
<hr>
<div class="small-12 column">
<%= render "pages/help/other" %>
</div>
</div>
</div>

View File

@@ -1,23 +0,0 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="budgets" data-magellan-target="budgets">
<%= t("pages.more_info.budgets.title") %>
</h3>
<p><%= t("pages.more_info.budgets.description") %></p>
<ul class="features">
<li>
<%= t("pages.more_info.budgets.feature_1",
link: link_to(t("pages.more_info.budgets.feature_1_link", org_name: setting['org_name']),
new_user_registration_path)).html_safe %>
</li>
<li><%= t("pages.more_info.budgets.feature_2_html") %></li>
<li><%= t("pages.more_info.budgets.feature_3_html") %></li>
<li><%= t("pages.more_info.budgets.feature_4_html") %></li>
</ul>
<figure>
<%= image_tag "more_info/budgets_#{I18n.locale}.png", alt: t("pages.more_info.budgets.image_alt") %>
<figcaption><%= t("pages.more_info.budgets.figcaption_html") %></figcaption>
</figure>
</div>
</div>

View File

@@ -1,21 +0,0 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="debates" data-magellan-target="debates">
<%= t("pages.more_info.debates.title") %>
</h3>
<p><%= t("pages.more_info.debates.description") %></p>
<ul class="features">
<li>
<%= t("pages.more_info.debates.feature_1",
link: link_to(t("pages.more_info.debates.feature_1_link", org_name: setting['org_name']),
new_user_registration_path)).html_safe %>
</li>
<li><%= t("pages.more_info.debates.feature_2_html") %></li>
</ul>
<figure>
<%= image_tag "more_info/debates.png", alt: t("pages.more_info.debates.image_alt") %>
<figcaption><%= t("pages.more_info.debates.figcaption") %></figcaption>
</figure>
</div>
</div>

View File

@@ -1,24 +0,0 @@
<div class="row">
<div class="small-12 column">
<ul class="menu-pages" data-magellan>
<% if feature?(:debates) %>
<li>
<%= link_to t("pages.more_info.menu.debates"), "#debates", class: "button hollow expanded" %>
</li>
<% end %>
<% if feature?(:proposals) %>
<li>
<%= link_to t("pages.more_info.menu.proposals"), "#proposals", class: "button hollow expanded" %>
</li>
<% end %>
<% if feature?(:budgets) %>
<li>
<%= link_to t("pages.more_info.menu.budgets"), "#budgets", class: "button hollow expanded" %>
</li>
<% end %>
<li>
<%= link_to t("pages.more_info.menu.other"), "#other", class: "button hollow expanded" %>
</li>
</ul>
</div>
</div>

View File

@@ -1,15 +0,0 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="polls" data-magellan-target="polls"><%= t("pages.more_info.polls.title") %></h3>
<p><%= t("pages.more_info.polls.description") %></p>
<ul class="features">
<li>
<%= t("pages.more_info.polls.feature_1",
link: link_to(t("pages.more_info.polls.feature_1_link", org_name: setting['org_name']),
new_user_registration_path)).html_safe %>
</li>
<li><%= t("pages.more_info.polls.feature_2") %></li>
<li><%= t("pages.more_info.polls.feature_3") %></li>
</ul>
</div>
</div>

View File

@@ -1,22 +0,0 @@
<div class="row section-content">
<div class="small-12 column">
<h3 id="proposals" data-magellan-target="proposals">
<%= t("pages.more_info.proposals.title") %>
</h3>
<p><%= t("pages.more_info.proposals.description") %></p>
<ul class="features">
<li>
<%= t("pages.more_info.proposals.feature_1",
link: link_to(t("pages.more_info.proposals.feature_1_link", org_name: setting['org_name']),
new_user_registration_path)).html_safe %>
</li>
<li><%= t("pages.more_info.proposals.feature_2_html") %></li>
<li><%= t("pages.more_info.proposals.feature_3_html") %></li>
</ul>
<figure>
<%= image_tag "more_info/proposals_#{I18n.locale}.png", alt: t("pages.more_info.proposals.image_alt") %>
<figcaption><%= t("pages.more_info.proposals.figcaption_html") %></figcaption>
</figure>
</div>
</div>

View File

@@ -1,5 +0,0 @@
<div class="sidebar-card">
<h3><%= t("pages.more_info.faq.title") %></h3>
<p><%= t("pages.more_info.faq.description") %></p>
<%= link_to t("pages.more_info.faq.button"), faq_path, class: "button expanded" %>
</div>

View File

@@ -1,21 +0,0 @@
<% content_for :canonical do %>
<%= render "shared/canonical", href: faq_url %>
<% end %>
<div class="row margin-top">
<div class="menu small-12 medium-3 column">
<%= back_link_to %>
<ul class="menu vertical margin-top">
<li><a href="#1"><strong><%= t("pages.more_info.faq.page.faq_1_title") %></strong></a></li>
</ul>
</div>
<div class="text small-12 medium-9 column">
<h1 class="clear"><%= t("pages.more_info.faq.page.title") %></h1>
<p><%= t("pages.more_info.faq.page.description") %></p>
<h2 id="1"><%= t("pages.more_info.faq.page.faq_1_title") %></h2>
<p><%= t("pages.more_info.faq.page.faq_1_description") %></p>
</div>
</div>

View File

@@ -1,48 +0,0 @@
<% provide :title do %><%= t("pages.titles.more_info", org_name: setting['org_name']) %><% end %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: more_info_url %>
<% end %>
<div class="jumbo light">
<div class="row">
<div class="small-12 column">
<h2><%= t("pages.more_info.title", org_name: setting['org_name']) %></h2>
<p class="lead"><%= t("pages.more_info.subtitle") %></p>
<p><%= t("pages.more_info.guide", org_name: setting['org_name']) %></p>
</div>
</div>
<%= render "pages/more_info/menu" %>
</div>
<div id="more-info" class="more-info-content">
<div class="row">
<div class="small-12 medium-7 large-8 column">
<% if feature?(:debates) %>
<%= render "pages/more_info/debates" %>
<% end %>
<% if feature?(:proposals) %>
<%= render "pages/more_info/proposals" %>
<% end %>
<% if feature?(:budgets) %>
<%= render "pages/more_info/budgets" %>
<% end %>
<% if feature?(:polls) %>
<%= render "pages/more_info/polls" %>
<% end %>
</div>
<div class="small-12 medium-4 large-3 column more-info-sidebar">
<%= render "pages/more_info/sidebar" %>
</div>
</div>
<div class="row">
<hr>
<div class="small-12 column">
<%= render "pages/more_info/other" %>
</div>
</div>
</div>

View File

@@ -5,7 +5,7 @@
<h1><%= t("proposals.new.start_new") %></h1> <h1><%= t("proposals.new.start_new") %></h1>
<div data-alert class="callout primary"> <div data-alert class="callout primary">
<%= link_to more_info_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %> <%= link_to help_path(anchor: "proposals") ,title: t('shared.target_blank_html'), target: "_blank" do %>
<%= t("proposals.new.more_info")%> <%= t("proposals.new.more_info")%>
<% end %> <% end %>
</div> </div>

View File

@@ -1,5 +1,5 @@
<div class="row"> <div class="row">
<div class="more-information small-12 medium-9 large-7 column"> <div class="help small-12 medium-9 large-7 column">
<h1>Más información</h1> <h1>Más información</h1>
<ul class="no-bullet"> <ul class="no-bullet">
<li> <li>

View File

@@ -1,14 +1,16 @@
<form class="inline-block"> <% if @valid_orders.present? && @valid_orders.count > 1 %>
<label for="order-selector-participation" class="show-for-sr"><%= t("#{i18n_namespace}.select_order") %></label> <form class="inline-block">
<select class="js-location-changer js-order-selector select-order" <label for="order-selector-participation" class="show-for-sr"><%= t("#{i18n_namespace}.select_order") %></label>
data-order="<%= @current_order %>" <select class="js-location-changer js-order-selector select-order"
name="order-selector" data-order="<%= @current_order %>"
id="order-selector-participation"> name="order-selector"
<% @valid_orders.each do |order| %> id="order-selector-participation">
<option <%= 'selected' if order == @current_order %> <% @valid_orders.each do |order| %>
value='<%= current_path_with_query_params(order: order, page: 1) %>'> <option <%= 'selected' if order == @current_order %>
<%= t("#{i18n_namespace}.orders.#{order}") %> value='<%= current_path_with_query_params(order: order, page: 1) %>'>
</option> <%= t("#{i18n_namespace}.orders.#{order}") %>
<% end %> </option>
</select> <% end %>
</form> </select>
</form>
<% end %>

View File

@@ -53,11 +53,11 @@
</li> </li>
<% end %> <% end %>
<li> <li>
<%= link_to t("layouts.header.more_info"), <%= link_to t("layouts.header.help"),
more_info_path, help_path,
accesskey: "5", accesskey: "5",
class: ("active" if current_page?(more_info_path)), class: ("active" if current_page?(help_path)),
title: t("shared.go_to_page") + t("layouts.header.more_info") %> title: t("shared.go_to_page") + t("layouts.header.help") %>
</li> </li>
</ul> </ul>
</div> </div>

View File

@@ -2,25 +2,26 @@
# #
# i18n_namespace: for example "moderation.debates.index" # i18n_namespace: for example "moderation.debates.index"
%> %>
<% if @valid_orders.present? && @valid_orders.count > 1 %>
<div class="wide-order-selector small-12 medium-8"> <div class="wide-order-selector small-12 medium-8">
<form> <form>
<div class="small-12 medium-6 float-left"> <div class="small-12 medium-6 float-left">
<label for="order-selector-participation"> <label for="order-selector-participation">
<%= t("#{i18n_namespace}.select_order") %> <%= t("#{i18n_namespace}.select_order") %>
</label> </label>
</div> </div>
<div class="small-12 medium-6 float-left"> <div class="small-12 medium-6 float-left">
<select class="js-location-changer js-order-selector select-order" <select class="js-location-changer js-order-selector select-order"
data-order="<%= @current_order %>" name="order-selector" data-order="<%= @current_order %>" name="order-selector"
id="order-selector-participation"> id="order-selector-participation">
<% @valid_orders.each do |order| %> <% @valid_orders.each do |order| %>
<% value = current_path_with_query_params(order: order, page: 1) %> <% value = current_path_with_query_params(order: order, page: 1) %>
<option value="<%= value %>" <%= 'selected' if order == @current_order %>> <option value="<%= value %>" <%= 'selected' if order == @current_order %>>
<%= t("#{i18n_namespace}.orders.#{order}") %> <%= t("#{i18n_namespace}.orders.#{order}") %>
</option> </option>
<% end %> <% end %>
</select> </select>
</div> </div>
</form> </form>
</div> </div>
<% end %>

View File

@@ -47,3 +47,11 @@
</p> </p>
<% end %> <% end %>
<div class="tabs-panel is-active" id="tab-comments">
<% unless @comment_tree.nil? %>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: false,
valuation: true } %>
<% end %>
</div>

View File

@@ -96,6 +96,15 @@
</div> </div>
<% end %> <% end %>
<div class="tabs-panel is-active" id="tab-comments">
<% unless @comment_tree.nil? %>
<%= render partial: '/comments/comment_tree', locals: { comment_tree: @comment_tree,
comment_flags: @comment_flags,
display_comments_count: false,
valuation: true } %>
<% end %>
</div>
<h1><%= @investment.title %></h1> <h1><%= @investment.title %></h1>
<%= safe_html_with_links @investment.description %> <%= safe_html_with_links @investment.description %>

View File

@@ -17,7 +17,7 @@
<%= t("layouts.header.open_city_slogan_html") %> <%= t("layouts.header.open_city_slogan_html") %>
</p> </p>
<div class="small-12 medium-6 large-4 small-centered"> <div class="small-12 medium-6 large-4 small-centered">
<%= link_to t("layouts.header.more_info"), more_info_path, class: "button expanded large" %> <%= link_to t("shared.more_info"), help_path, class: "button expanded large" %>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -19,7 +19,7 @@ module Consul
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :es config.i18n.default_locale = :en
config.i18n.available_locales = [:en, :es, :fr, :nl, 'pt-BR'] config.i18n.available_locales = [:en, :es, :fr, :nl, 'pt-BR']
config.i18n.fallbacks = {'fr' => 'es', 'pt-br' => 'es', 'nl' => 'en'} config.i18n.fallbacks = {'fr' => 'es', 'pt-br' => 'es', 'nl' => 'en'}
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')] config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]

View File

@@ -187,7 +187,7 @@ en:
status: Status status: Status
title: Title title: Title
updated_at: Updated at updated_at: Updated at
more_info_flag: Show in more information page more_info_flag: Show in help page
print_content_flag: Print content button print_content_flag: Print content button
locale: Language locale: Language
site_customization/image: site_customization/image:
@@ -296,6 +296,10 @@ en:
image: image:
image_width: "Width must be %{required_width}px" image_width: "Width must be %{required_width}px"
image_height: "Height must be %{required_height}px" image_height: "Height must be %{required_height}px"
comment:
attributes:
valuation:
cannot_comment_valuation: 'You cannot comment a valuation'
messages: messages:
record_invalid: "Validation failed: %{errors}" record_invalid: "Validation failed: %{errors}"
restrict_dependent_destroy: restrict_dependent_destroy:

View File

@@ -231,7 +231,7 @@ en:
moderation: Moderation moderation: Moderation
valuation: Valuation valuation: Valuation
officing: Polling officers officing: Polling officers
more_info: More information help: Help
my_account_link: My account my_account_link: My account
my_activity_link: My activity my_activity_link: My activity
notifications: Notifications notifications: Notifications
@@ -623,6 +623,7 @@ en:
previous_slide: Previous Slide previous_slide: Previous Slide
next_slide: Next Slide next_slide: Next Slide
documentation: Additional documentation documentation: Additional documentation
more_info: More information
social: social:
blog: "%{org} Blog" blog: "%{org} Blog"
facebook: "%{org} Facebook" facebook: "%{org} Facebook"

View File

@@ -3,10 +3,10 @@ en:
census_terms: To confirm the account, you must be 16 or older and be registered, having provided the information requested previously, will verify. By accepting the verification process, you also consent to the verification of this information, as well as the contact methods featuring in said files. The data provided will be acquired and processed in a file mentioned previously in the terms and conditions of use for the Portal. census_terms: To confirm the account, you must be 16 or older and be registered, having provided the information requested previously, will verify. By accepting the verification process, you also consent to the verification of this information, as well as the contact methods featuring in said files. The data provided will be acquired and processed in a file mentioned previously in the terms and conditions of use for the Portal.
conditions: Terms and conditions of use conditions: Terms and conditions of use
general_terms: Terms and Conditions general_terms: Terms and Conditions
more_info: help:
title: "Discover %{org_name}" title: "%{org} is a platform for citizen participation"
subtitle: "Learn everything you can do on this website." subtitle: "In %{org} you can make proposals, vote in citizen consultations, propose participatory budget projects, decide on municipal regulations and open debates to exchange opinions with others."
guide: 'This guide explains each section of %{org_name}. You can expand the information on "Detailed information" links.' guide: "This guide explains what each of the %{org} sections are for and how they work."
menu: menu:
debates: "Debates" debates: "Debates"
proposals: "Proposals" proposals: "Proposals"
@@ -14,38 +14,39 @@ en:
other: "Other information of interest" other: "Other information of interest"
debates: debates:
title: "Debates" title: "Debates"
description: "Create a thread where you can discuss any topic you want to share with other people in your city." description: "In the %{link} section you can present and share your opinion with other people on issues of concern to you related to the city. It is also a place to generate ideas that through the other sections of %{org} lead to concrete actions by the City Council."
feature_1: "To create a debate you have to %{link}" link: "citizen debates"
feature_1_link: "sign up on %{org_name}" feature_html: "You can open debates, comment and evaluate them with the <strong>I agree</strong> or <strong>I don't agree</strong>. For that you have to %{link}."
feature_2_html: "Debates can be rated using the <strong>I agree</strong> or <strong>I disagree</strong> buttons you'll find on each of them." feature_link: "register in %{org}"
image_alt: "Buttons to rate the debates" image_alt: "Buttons to rate the debates"
figcaption: '"I agree" and "I disagree" buttons to rate the debates.' figcaption: '"I agree" and "I disagree" buttons to rate the debates.'
proposals: proposals:
title: "Proposals" title: "Proposals"
description: "Propose what you want the City Council to do and support proposals from other people." description: "In the %{link} section you can make proposals for the City Council to carry them out. The proposals require support, and if they reach sufficient support, they are put to a public vote. The proposals approved in these citizens' votes are accepted by the City Council and carried out."
feature_1: "To create a proposal you have to %{link}, in addition to support you must verify your account." link: "citizen proposals"
feature_1_link: "sign up on %{org_name}" feature_html: "To create a proposal you must register in %{org}. The proposals that get the support on the website of 1% of people with the right to vote (%{supports} supports of people over 16 years old registered) go to vote. To support proposals it is necessary to verify your account."
feature_2_html: "Proposals that get <strong>support from 1% of people</strong> will be voted on."
feature_3_html: "If there are more people in favor than against, <strong>the City Council will publish their plan to accomplish</strong> the proposal and you can track its progress."
image_alt: "Button to support a proposal" image_alt: "Button to support a proposal"
figcaption_html: 'Button to "Support" a proposal.<br>When it reaches the number of supports will go to vote.' figcaption_html: 'Button to "Support" a proposal.<br>When it reaches the number of supports will go to vote.'
budgets: budgets:
title: "Participatory Budgeting" title: "Participatory Budgeting"
description: "The first six months of each year you can decide how to spend part of the budget." description: "The %{link} section helps people make a direct decision on what part of the municipal budget is spent on."
feature_1: "To submit an investment project you have to %{link} and verify your account." link: "participative budgets"
feature_1_link: "sign up on %{org_name}" feature: "In this process, every year people raise, support and vote on projects. The most voted votes are financed by the municipal budget."
feature_2_html: "The first is the <strong>submit phase</strong> of investment projects." phase_1_html: "Between January and early March, people registered in %{org} can <strong>present</strong>."
feature_3_html: "Then there is a <strong>support phase</strong> to prioritize the most interesting, the most supported are evaluated by the City to see if they are viable and how much they are worth." phase_2_html: "In March, proposers have to gather support, in the form of <strong>preselection</strong>."
feature_4_html: "At the end there is a <strong>vote phase </strong> and you decide which of the approved projects to spend the budget on." phase_3_html: "Between April and the beginning of May, the experts from the <strong>City Council rate</strong> projects on an order of more or less supported and check that they are viable."
phase_4_html: "Finally, between May and June, all citizens can <strong>vote</strong> projects that interest them the most."
phase_5_html: "From the approval of the budgets the following year the City Council begins to carry out the winning projects."
image_alt: "Different phases of a participatory budget" image_alt: "Different phases of a participatory budget"
figcaption_html: '"Support" and "Voting" phases of participatory budgets.' figcaption_html: '"Support" and "Voting" phases of participatory budgets.'
polls: polls:
title: "Polls" title: "Polls"
description: "Citizen proposals that reach 1% of support will be put to a vote." description: "The %{link} section is activated each time a proposal reaches 1% support and goes to the vote or when the City Council proposes an issue for people to decide on."
feature_1: "To participate in the next poll you have to %{link} and verify your account." link: "polls"
feature_1_link: "sign up on %{org_name}" feature_1: "To participate in the voting you have to %{link} and verify your account."
feature_2: "All verified users over 16 years old can vote." feature_1_link: "register in %{org_name}"
feature_3: "The results of all votes shall be binding on the government." feature_2: "All registered voters over the age of 16 can vote."
feature_3: "The results of all votes are binding on the municipal government."
faq: faq:
title: "Technical problems?" title: "Technical problems?"
description: "Read the FAQs and solve your questions." description: "Read the FAQs and solve your questions."
@@ -71,7 +72,7 @@ en:
titles: titles:
accessibility: Accessibility accessibility: Accessibility
conditions: Terms of use conditions: Terms of use
more_info: "More information about %{org_name}" help: "What is %{org}? - Citizen participation"
privacy: Privacy Policy privacy: Privacy Policy
verify: verify:
code: Code you received in letter code: Code you received in letter

View File

@@ -183,7 +183,7 @@ es:
status: Estado status: Estado
title: Título title: Título
updated_at: última actualización updated_at: última actualización
more_info_flag: Mostrar en la página de más información more_info_flag: Mostrar en la página de ayuda
print_content_flag: Botón de imprimir contenido print_content_flag: Botón de imprimir contenido
locale: Idioma locale: Idioma
site_customization/image: site_customization/image:
@@ -292,6 +292,10 @@ es:
image: image:
image_width: "Debe tener %{required_width}px de ancho" image_width: "Debe tener %{required_width}px de ancho"
image_height: "Debe tener %{required_height}px de alto" image_height: "Debe tener %{required_height}px de alto"
comment:
attributes:
valuation:
cannot_comment_valuation: 'No puedes comentar una evaluación'
messages: messages:
record_invalid: 'Error de validación: %{errors}' record_invalid: 'Error de validación: %{errors}'
restrict_dependent_destroy: restrict_dependent_destroy:

View File

@@ -231,7 +231,7 @@ es:
moderation: Moderar moderation: Moderar
valuation: Evaluación valuation: Evaluación
officing: Presidentes de mesa officing: Presidentes de mesa
more_info: Más información help: Ayuda
my_account_link: Mi cuenta my_account_link: Mi cuenta
my_activity_link: Mi actividad my_activity_link: Mi actividad
notifications: Notificaciones notifications: Notificaciones
@@ -622,6 +622,7 @@ es:
previous_slide: Imagen anterior previous_slide: Imagen anterior
next_slide: Siguiente imagen next_slide: Siguiente imagen
documentation: Documentación adicional documentation: Documentación adicional
more_info: Más información
social: social:
blog: "Blog de %{org}" blog: "Blog de %{org}"
facebook: "Facebook de %{org}" facebook: "Facebook de %{org}"

View File

@@ -3,10 +3,10 @@ es:
census_terms: Para verificar la cuenta hay que tener 16 años o más y estar empadronado aportando los datos indicados anteriormente, los cuales serán contrastados. Aceptando el proceso de verificación acepta dar su consentimiento para contrastar dicha información, así como medios de contacto que figuren en dichos ficheros. Los datos aportados serán incorporados y tratados en un fichero indicado anteriormente en las condiciones de uso del portal. census_terms: Para verificar la cuenta hay que tener 16 años o más y estar empadronado aportando los datos indicados anteriormente, los cuales serán contrastados. Aceptando el proceso de verificación acepta dar su consentimiento para contrastar dicha información, así como medios de contacto que figuren en dichos ficheros. Los datos aportados serán incorporados y tratados en un fichero indicado anteriormente en las condiciones de uso del portal.
conditions: Condiciones de uso conditions: Condiciones de uso
general_terms: Términos y Condiciones general_terms: Términos y Condiciones
more_info: help:
title: "Descubre %{org_name}" title: "%{org} es una plataforma de participación ciudadana"
subtitle: "Aprende todo lo que puedes hacer en esta web." subtitle: "En %{org} se pueden hacer propuestas, votar en consultas ciudadanas, plantear proyectos de presupuestos participativos, decidir la normativa municipal y abrir debates para intercambiar opiniones con otras personas."
guide: 'Esta guía explica cada una de las secciones de %{org_name}. Puedes ampliar la información en los enlaces de "Información detallada".' guide: 'Esta guía explica para qué sirven y cómo funcionan cada una de las secciones de %{org}.'
menu: menu:
debates: "Debates" debates: "Debates"
proposals: "Propuestas" proposals: "Propuestas"
@@ -14,38 +14,39 @@ es:
other: "Otra información de interés" other: "Otra información de interés"
debates: debates:
title: "Debates" title: "Debates"
description: "Crea un hilo en el que debatir sobre cualquier tema que quieras compartir con el resto de gente de tu ciudad." description: "En la sección de %{link} puedes exponer y compartir tu opinión con otras personas sobre temas que te preocupan relacionados con la ciudad. También es un espacio donde generar ideas que a través de las otras secciones de %{org} lleven a actuaciones concretas por parte del Ayuntamiento."
feature_1: "Para crear un debate tienes que %{link}" link: "debates ciudadanos"
feature_1_link: "registrarte en %{org_name}" feature_html: "Puedes abrir debates, comentarlos y valorarlos con los botones de <strong>Estoy de acuerdo</strong> o <strong>No estoy de acuerdo</strong>. Para ello tienes que %{link}."
feature_2_html: "Los debates pueden ser valorados utilizando los botones de <strong>Estoy de acuerdo</strong> o <strong>No estoy de acuerdo</strong> que encontrarás en cada uno de ellos." feature_link: "registrarte en %{org}"
image_alt: "Botones para valorar los debates" image_alt: "Botones para valorar los debates"
figcaption: 'Botones "Estoy de acuerdo" y "No estoy de acuerdo" para valorar los debates.' figcaption: 'Botones "Estoy de acuerdo" y "No estoy de acuerdo" para valorar los debates.'
proposals: proposals:
title: "Propuestas" title: "Propuestas"
description: "Propón lo que quieres que el Ayuntamiento lleve a cabo y apoya propuestas de otras personas." description: "En la sección de %{link} puedes plantear propuestas para que el Ayuntamiento las lleve a cabo. Las propuestas recaban apoyos, y si alcanzan los apoyos suficientes se someten a votación ciudadana. Las propuestas aprobadas en estas votaciones ciudadanas son asumidas por el Ayuntamiento y se llevan a cabo."
feature_1: "Para crear una propuesta tienes que %{link}, además para apoyarlas debes verificar tu cuenta." link: "propuestas ciudadanas"
feature_1_link: "registrarte en %{org_name}" feature_html: "Para crear una propuesta hay que registrarse en %{org}. Las propuestas que consiguen el apoyo en la web del 1% de la gente con derecho a voto (%{supports} apoyos de personas mayores de 16 años empadronadas) pasan a votación. Para apoyar propuestas es necesario verificar tu cuenta."
feature_2_html: "Las propuestas que consigan <strong>el apoyo del 1% de la gente</strong> (mayor de 16 años empadronada; %{supports} apoyos) pasan a votación."
feature_3_html: "Si hay más gente a favor que en contra en la votación, <strong>el Ayuntamiento asume la propuesta y se hace</strong>."
image_alt: "Botón para apoyar una propuesta" image_alt: "Botón para apoyar una propuesta"
figcaption_html: 'Botón para "Apoyar" una propuesta.<br>Cuando alcance el número de apoyos pasará a votación.' figcaption_html: 'Botón para "Apoyar" una propuesta.<br>Cuando alcance el número de apoyos pasará a votación.'
budgets: budgets:
title: "Presupuestos participativos" title: "Presupuestos participativos"
description: "Los primeros seis meses de cada año puedes decidir cómo gastar parte del presupuesto." description: "La sección de %{link} sirve para que la gente decida de manera directa a qué se destina una parte del presupuesto municipal."
feature_1: "Para crear un proyecto de gasto tienes que %{link} y verificar tu cuenta." link: "presupuestos participativos"
feature_1_link: "registrarte en %{org_name}" feature: "En este proceso cada año la gente plantea, apoya y vota proyectos. Los más votados pasan a financiarse con el presupuesto municipal."
feature_2_html: "En primer lugar empieza la <strong>fase de aceptación</strong> de proyectos de gasto." phase_1_html: "Entre enero y principios de marzo, las personas registradas en %{org} pueden <strong>presentar proyectos</strong>."
feature_3_html: "Después hay una <strong>fase de apoyos</strong> para priorizar lo más interesante, las más apoyadas son evaluadas por el Ayuntamiento para ver si son viables y cuánto valen." phase_2_html: "En marzo, los proponentes tienen que recabar apoyos, a modo de <strong>fase de preselección</strong>."
feature_4_html: "Al final hay una <strong>fase de votación</strong> donde se decide en cuáles se gasta esa parte del presupuesto." phase_3_html: "Entre abril y comienzos de mayo los técnicos del Ayuntamiento <strong>tasan los proyectos</strong> por orden de más a menos apoyados y comprueban que son viables."
phase_4_html: "Finalmente, entre mayo y junio, toda la ciudadanía puede <strong>votar los proyectos</strong> que más le interesan."
phase_5_html: "A partir de la aprobación de los presupuestos al año siguiente el Ayuntamiento empieza a llevar a cabo los proyectos ganadores."
image_alt: "Diferentes fases de un presupuesto participativo" image_alt: "Diferentes fases de un presupuesto participativo"
figcaption_html: 'Fase de "Apoyos" y fase de "Votación" de los presupuestos participativos.' figcaption_html: 'Fase de "Apoyos" y fase de "Votación" de los presupuestos participativos.'
polls: polls:
title: "Votaciones" title: "Votaciones"
description: "Las propuestas ciudadanas que alcancen el 1% de apoyos pasarán a votación." description: "La sección de %{link} se activa cada vez que una propuesta alcanza el 1% de apoyos y pasa a votación o cuando el Ayuntamiento propone un tema para que la gente decida sobre él."
feature_1: "Para participar en la próxima votación tienes que %{link} y verificar tu cuenta." link: "votaciones ciudadanas"
feature_1: "Para participar en las votaciones tienes que %{link} y verificar tu cuenta."
feature_1_link: "registrarte en %{org_name}" feature_1_link: "registrarte en %{org_name}"
feature_2: "Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años." feature_2: "Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años."
feature_3: "Los resultados de todas las votaciones serán vinculantes para el gobierno." feature_3: "Los resultados de todas las votaciones son vinculantes para el gobierno municipal."
faq: faq:
title: "¿Problemas técnicos?" title: "¿Problemas técnicos?"
description: "Lee las preguntas frecuentes y resuelve tus dudas." description: "Lee las preguntas frecuentes y resuelve tus dudas."
@@ -71,7 +72,7 @@ es:
titles: titles:
accessibility: Accesibilidad accessibility: Accesibilidad
conditions: Condiciones de uso conditions: Condiciones de uso
more_info: "Más información sobre %{org_name}" help: "¿Qué es %{org}? - Participación ciudadana"
privacy: Política de Privacidad privacy: Política de Privacidad
verify: verify:
code: Código que has recibido en tu carta code: Código que has recibido en tu carta

View File

@@ -42,9 +42,9 @@ Rails.application.routes.draw do
resources :follows, only: [:create, :destroy] resources :follows, only: [:create, :destroy]
# More info pages # More info pages
get 'more-information', to: 'pages#show', id: 'more_info/index', as: 'more_info' get 'help', to: 'pages#show', id: 'help/index', as: 'help'
get 'more-information/how-to-use', to: 'pages#show', id: 'more_info/how_to_use/index', as: 'how_to_use' get 'help/how-to-use', to: 'pages#show', id: 'help/how_to_use/index', as: 'how_to_use'
get 'more-information/faq', to: 'pages#show', id: 'more_info/faq/index', as: 'faq' get 'help/faq', to: 'pages#show', id: 'help/faq/index', as: 'faq'
# Static pages # Static pages
get '/blog' => redirect("http://blog.consul/") get '/blog' => redirect("http://blog.consul/")

View File

@@ -14,7 +14,7 @@ SitemapGenerator::Sitemap.create do
add page_path(id: page) add page_path(id: page)
end end
add more_info_path add help_path
add how_to_use_path add how_to_use_path
add faq_path add faq_path

View File

@@ -319,114 +319,6 @@ section "Creating Successful Proposals" do
end end
end end
section "Commenting Debates" do
100.times do
author = User.all.sample
debate = Debate.all.sample
Comment.create!(user: author,
created_at: rand(debate.created_at..Time.current),
commentable: debate,
body: Faker::Lorem.sentence)
end
end
section "Commenting Proposals" do
100.times do
author = User.all.sample
proposal = Proposal.all.sample
Comment.create!(user: author,
created_at: rand(proposal.created_at..Time.current),
commentable: proposal,
body: Faker::Lorem.sentence)
end
end
section "Commenting Comments" do
200.times do
author = User.all.sample
parent = Comment.all.sample
Comment.create!(user: author,
created_at: rand(parent.created_at..Time.current),
commentable_id: parent.commentable_id,
commentable_type: parent.commentable_type,
body: Faker::Lorem.sentence,
parent: parent)
end
end
section "Voting Debates, Proposals & Comments" do
not_org_users = User.where(['users.id NOT IN(?)', User.organizations.pluck(:id)])
100.times do
voter = not_org_users.level_two_or_three_verified.all.sample
vote = [true, false].sample
debate = Debate.all.sample
debate.vote_by(voter: voter, vote: vote)
end
100.times do
voter = not_org_users.all.sample
vote = [true, false].sample
comment = Comment.all.sample
comment.vote_by(voter: voter, vote: vote)
end
100.times do
voter = not_org_users.level_two_or_three_verified.all.sample
proposal = Proposal.all.sample
proposal.vote_by(voter: voter, vote: true)
end
end
section "Flagging Debates & Comments" do
40.times do
debate = Debate.all.sample
flagger = User.where(["users.id <> ?", debate.author_id]).all.sample
Flag.flag(flagger, debate)
end
40.times do
comment = Comment.all.sample
flagger = User.where(["users.id <> ?", comment.user_id]).all.sample
Flag.flag(flagger, comment)
end
40.times do
proposal = Proposal.all.sample
flagger = User.where(["users.id <> ?", proposal.author_id]).all.sample
Flag.flag(flagger, proposal)
end
end
section "Creating Spending Proposals" do
tags = Faker::Lorem.words(10)
60.times do
geozone = Geozone.all.sample
author = User.all.sample
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
feasible_explanation = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
valuation_finished = [true, false].sample
feasible = [true, false].sample
spending_proposal = SpendingProposal.create!(author: author,
title: Faker::Lorem.sentence(3).truncate(60),
external_url: Faker::Internet.url,
description: description,
created_at: rand((Time.current - 1.week)..Time.current),
geozone: [geozone, nil].sample,
feasible: feasible,
feasible_explanation: feasible_explanation,
valuation_finished: valuation_finished,
tag_list: tags.sample(3).join(','),
price: rand(1000000),
terms_of_service: "1")
end
end
section "Creating Valuation Assignments" do
(1..17).to_a.sample.times do
SpendingProposal.all.sample.valuators << Valuator.first
end
end
section "Creating Budgets" do section "Creating Budgets" do
Budget.create( Budget.create(
name: "Budget #{Date.current.year - 1}", name: "Budget #{Date.current.year - 1}",
@@ -533,6 +425,104 @@ section "Creating Valuation Assignments" do
end end
end end
section "Commenting Investments, Debates & Proposals" do
%w(Budget::Investment Debate Proposal).each do |commentable_class|
100.times do
commentable = commentable_class.constantize.all.sample
Comment.create!(user: User.all.sample,
created_at: rand(commentable.created_at..Time.current),
commentable: commentable,
body: Faker::Lorem.sentence)
end
end
end
section "Commenting Comments" do
200.times do
parent = Comment.all.sample
Comment.create!(user: User.all.sample,
created_at: rand(parent.created_at..Time.current),
commentable_id: parent.commentable_id,
commentable_type: parent.commentable_type,
body: Faker::Lorem.sentence,
parent: parent)
end
end
section "Voting Debates, Proposals & Comments" do
not_org_users = User.where(['users.id NOT IN(?)', User.organizations.pluck(:id)])
100.times do
voter = not_org_users.level_two_or_three_verified.all.sample
vote = [true, false].sample
debate = Debate.all.sample
debate.vote_by(voter: voter, vote: vote)
end
100.times do
voter = not_org_users.all.sample
vote = [true, false].sample
comment = Comment.all.sample
comment.vote_by(voter: voter, vote: vote)
end
100.times do
voter = not_org_users.level_two_or_three_verified.all.sample
proposal = Proposal.all.sample
proposal.vote_by(voter: voter, vote: true)
end
end
section "Flagging Debates & Comments" do
40.times do
debate = Debate.all.sample
flagger = User.where(["users.id <> ?", debate.author_id]).all.sample
Flag.flag(flagger, debate)
end
40.times do
comment = Comment.all.sample
flagger = User.where(["users.id <> ?", comment.user_id]).all.sample
Flag.flag(flagger, comment)
end
40.times do
proposal = Proposal.all.sample
flagger = User.where(["users.id <> ?", proposal.author_id]).all.sample
Flag.flag(flagger, proposal)
end
end
section "Creating Spending Proposals" do
tags = Faker::Lorem.words(10)
60.times do
geozone = Geozone.all.sample
author = User.all.sample
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
feasible_explanation = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
valuation_finished = [true, false].sample
feasible = [true, false].sample
created_at = rand((Time.current - 1.week)..Time.current)
spending_proposal = SpendingProposal.create!(author: author,
title: Faker::Lorem.sentence(3).truncate(60),
external_url: Faker::Internet.url,
description: description,
created_at: created_at,
geozone: [geozone, nil].sample,
feasible: feasible,
feasible_explanation: feasible_explanation,
valuation_finished: valuation_finished,
tag_list: tags.sample(3).join(','),
price: rand(1000000),
terms_of_service: "1")
end
end
section "Creating Valuation Assignments" do
(1..17).to_a.sample.times do
SpendingProposal.all.sample.valuators << Valuator.first
end
end
section "Ignoring flags in Debates, comments & proposals" do section "Ignoring flags in Debates, comments & proposals" do
Debate.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag) Debate.flagged.reorder("RANDOM()").limit(10).each(&:ignore_flag)
Comment.flagged.reorder("RANDOM()").limit(30).each(&:ignore_flag) Comment.flagged.reorder("RANDOM()").limit(30).each(&:ignore_flag)
@@ -555,13 +545,16 @@ section "Creating banners" do
Proposal.last(3).each do |proposal| Proposal.last(3).each do |proposal|
title = Faker::Lorem.sentence(word_count = 3) title = Faker::Lorem.sentence(word_count = 3)
description = Faker::Lorem.sentence(word_count = 12) description = Faker::Lorem.sentence(word_count = 12)
target_url = Rails.application.routes.url_helpers.proposal_path(proposal)
banner = Banner.create!(title: title, banner = Banner.create!(title: title,
description: description, description: description,
style: ["banner-style banner-style-one", "banner-style banner-style-two", style: ["banner-style banner-style-one",
"banner-style banner-style-two",
"banner-style banner-style-three"].sample, "banner-style banner-style-three"].sample,
image: ["banner-img banner-img-one", "banner-img banner-img-two", image: ["banner-img banner-img-one",
"banner-img banner-img-two",
"banner-img banner-img-three"].sample, "banner-img banner-img-three"].sample,
target_url: Rails.application.routes.url_helpers.proposal_path(proposal), target_url: target_url,
post_started_at: rand((Time.current - 1.week)..(Time.current - 1.day)), post_started_at: rand((Time.current - 1.week)..(Time.current - 1.day)),
post_ended_at: rand((Time.current - 1.day)..(Time.current + 1.week)), post_ended_at: rand((Time.current - 1.day)..(Time.current + 1.week)),
created_at: rand((Time.current - 1.week)..Time.current)) created_at: rand((Time.current - 1.week)..Time.current))
@@ -616,9 +609,10 @@ section "Creating Poll Questions & Answers" do
title: Faker::Lorem.sentence(3).truncate(60) + '?', title: Faker::Lorem.sentence(3).truncate(60) + '?',
poll: poll) poll: poll)
Faker::Lorem.words((2..4).to_a.sample).each do |answer| Faker::Lorem.words((2..4).to_a.sample).each do |answer|
description = "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>"
Poll::Question::Answer.create!(question: question, Poll::Question::Answer.create!(question: question,
title: answer.capitalize, title: answer.capitalize,
description: "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>") description: description)
end end
end end
end end
@@ -626,17 +620,20 @@ end
section "Creating Poll Booths & BoothAssignments" do section "Creating Poll Booths & BoothAssignments" do
20.times do |i| 20.times do |i|
Poll::Booth.create(name: "Booth #{i}", location: Faker::Address.street_address, polls: [Poll.all.sample]) Poll::Booth.create(name: "Booth #{i}",
location: Faker::Address.street_address,
polls: [Poll.all.sample])
end end
end end
section "Creating Poll Shifts for Poll Officers" do section "Creating Poll Shifts for Poll Officers" do
Poll.all.each do |poll| Poll.all.each do |poll|
Poll::BoothAssignment.where(poll: poll).each do |booth_assignment| Poll::BoothAssignment.where(poll: poll).each do |booth_assignment|
scrutiny = (poll.ends_at.to_datetime..poll.ends_at.to_datetime + Poll::RECOUNT_DURATION)
Poll::Officer.all.each do |poll_officer| Poll::Officer.all.each do |poll_officer|
{ {
vote_collection: (poll.starts_at.to_datetime..poll.ends_at.to_datetime), vote_collection: (poll.starts_at.to_datetime..poll.ends_at.to_datetime),
recount_scrutiny: (poll.ends_at.to_datetime..poll.ends_at.to_datetime + Poll::RECOUNT_DURATION) recount_scrutiny: scrutiny
}.each do |task_name, task_dates| }.each do |task_name, task_dates|
task_dates.each do |shift_date| task_dates.each do |shift_date|
Poll::Shift.create(booth: booth_assignment.booth, Poll::Shift.create(booth: booth_assignment.booth,
@@ -710,13 +707,17 @@ section "Creating Poll Voters" do
def randomly_answer_questions(poll, user) def randomly_answer_questions(poll, user)
poll.questions.each do |question| poll.questions.each do |question|
next unless [true, false].sample next unless [true, false].sample
Poll::Answer.create!(question_id: question.id, author: user, answer: question.question_answers.sample.title) Poll::Answer.create!(question_id: question.id,
author: user,
answer: question.question_answers.sample.title)
end end
end end
(Poll.expired + Poll.current + Poll.recounting).uniq.each do |poll| (Poll.expired + Poll.current + Poll.recounting).uniq.each do |poll|
level_two_verified_users = User.level_two_verified level_two_verified_users = User.level_two_verified
level_two_verified_users = level_two_verified_users.where(geozone_id: poll.geozone_ids) if poll.geozone_restricted? if poll.geozone_restricted?
level_two_verified_users = level_two_verified_users.where(geozone_id: poll.geozone_ids)
end
user_groups = level_two_verified_users.in_groups(2) user_groups = level_two_verified_users.in_groups(2)
user_groups.first.each { |user| vote_poll_on_booth(user, poll) } user_groups.first.each { |user| vote_poll_on_booth(user, poll) }
user_groups.second.compact.each { |user| vote_poll_on_web(user, poll) } user_groups.second.compact.each { |user| vote_poll_on_web(user, poll) }
@@ -769,7 +770,9 @@ section "Creating Poll Questions from Proposals" do
poll = Poll.current.first poll = Poll.current.first
question = Poll::Question.create(poll: poll) question = Poll::Question.create(poll: poll)
Faker::Lorem.words((2..4).to_a.sample).each do |answer| Faker::Lorem.words((2..4).to_a.sample).each do |answer|
Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact) Poll::Question::Answer.create!(question: question,
title: answer.capitalize,
description: Faker::ChuckNorris.fact)
end end
question.copy_attributes_from_proposal(proposal) question.copy_attributes_from_proposal(proposal)
question.save! question.save!
@@ -782,7 +785,9 @@ section "Creating Successful Proposals" do
poll = Poll.current.first poll = Poll.current.first
question = Poll::Question.create(poll: poll) question = Poll::Question.create(poll: poll)
Faker::Lorem.words((2..4).to_a.sample).each do |answer| Faker::Lorem.words((2..4).to_a.sample).each do |answer|
Poll::Question::Answer.create!(question: question, title: answer.capitalize, description: Faker::ChuckNorris.fact) Poll::Question::Answer.create!(question: question,
title: answer.capitalize,
description: Faker::ChuckNorris.fact)
end end
question.copy_attributes_from_proposal(proposal) question.copy_attributes_from_proposal(proposal)
question.save! question.save!

View File

@@ -0,0 +1,5 @@
class AddValuationFlagToComments < ActiveRecord::Migration
def change
add_column :comments, :valuation, :boolean, default: false
end
end

View File

@@ -0,0 +1,7 @@
class AddIndexToValuationComments < ActiveRecord::Migration
disable_ddl_transaction!
def change
add_index :comments, :valuation, algorithm: :concurrently
end
end

View File

@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20180119073228) do ActiveRecord::Schema.define(version: 20180129190950) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -234,7 +234,7 @@ ActiveRecord::Schema.define(version: 20180119073228) do
t.string "commentable_type" t.string "commentable_type"
t.text "body" t.text "body"
t.string "subject" t.string "subject"
t.integer "user_id", null: false t.integer "user_id", null: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.datetime "hidden_at" t.datetime "hidden_at"
@@ -247,7 +247,8 @@ ActiveRecord::Schema.define(version: 20180119073228) do
t.integer "cached_votes_down", default: 0 t.integer "cached_votes_down", default: 0
t.datetime "confirmed_hide_at" t.datetime "confirmed_hide_at"
t.string "ancestry" t.string "ancestry"
t.integer "confidence_score", default: 0, null: false t.integer "confidence_score", default: 0, null: false
t.boolean "valuation", default: false
end end
add_index "comments", ["ancestry"], name: "index_comments_on_ancestry", using: :btree add_index "comments", ["ancestry"], name: "index_comments_on_ancestry", using: :btree
@@ -257,6 +258,7 @@ ActiveRecord::Schema.define(version: 20180119073228) do
add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree
add_index "comments", ["hidden_at"], name: "index_comments_on_hidden_at", using: :btree add_index "comments", ["hidden_at"], name: "index_comments_on_hidden_at", using: :btree
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
add_index "comments", ["valuation"], name: "index_comments_on_valuation", using: :btree
create_table "communities", force: :cascade do |t| create_table "communities", force: :cascade do |t|
t.datetime "created_at", null: false t.datetime "created_at", null: false

View File

@@ -112,7 +112,7 @@ Setting['mailer_from_address'] = 'noreply@consul.dev'
Setting['verification_offices_url'] = 'http://oficinas-atencion-ciudadano.url/' Setting['verification_offices_url'] = 'http://oficinas-atencion-ciudadano.url/'
Setting['min_age_to_participate'] = 16 Setting['min_age_to_participate'] = 16
# Proposal improvement url path ('/more-information/proposal-improvement') # Proposal improvement url path ('/help/proposal-improvement')
Setting['proposal_improvement_path'] = nil Setting['proposal_improvement_path'] = nil
# City map feature default configuration (Greenwich) # City map feature default configuration (Greenwich)

View File

@@ -4,16 +4,24 @@ class CommentTree
attr_accessor :root_comments, :comments, :commentable, :page, :order attr_accessor :root_comments, :comments, :commentable, :page, :order
def initialize(commentable, page, order = 'confidence_score') def initialize(commentable, page, order = 'confidence_score', valuations: false)
@commentable = commentable @commentable = commentable
@page = page @page = page
@order = order @order = order
@valuations = valuations
@comments = root_comments + root_descendants @comments = root_comments + root_descendants
end end
def root_comments def root_comments
commentable.comments.roots.send("sort_by_#{order}").page(page).per(ROOT_COMMENTS_PER_PAGE).for_render base_comments.roots.send("sort_by_#{order}").page(page).per(ROOT_COMMENTS_PER_PAGE).for_render
end
def base_comments
if @valuations && commentable.respond_to?('valuations')
commentable.valuations
else
commentable.comments
end
end end
def root_descendants def root_descendants

View File

@@ -32,17 +32,17 @@ describe PagesController do
describe 'More info pages' do describe 'More info pages' do
it 'includes a more info page' do it 'includes a more info page' do
get :show, id: 'more_info/index' get :show, id: 'help/index'
expect(response).to be_ok expect(response).to be_ok
end end
it 'includes a how_to_use page' do it 'includes a how_to_use page' do
get :show, id: 'more_info/how_to_use/index' get :show, id: 'help/how_to_use/index'
expect(response).to be_ok expect(response).to be_ok
end end
it 'includes a faq page' do it 'includes a faq page' do
get :show, id: 'more_info/faq/index' get :show, id: 'help/faq/index'
expect(response).to be_ok expect(response).to be_ok
end end
end end

View File

@@ -465,6 +465,16 @@ FactoryBot.define do
trait :with_confidence_score do trait :with_confidence_score do
before(:save) { |d| d.calculate_confidence_score } before(:save) { |d| d.calculate_confidence_score }
end end
trait :valuation do
valuation true
association :commentable, factory: :budget_investment
before :create do |valuation|
valuator = create(:valuator)
valuation.author = valuator.user
valuation.commentable.valuators << valuator
end
end
end end
factory :legacy_legislation do factory :legacy_legislation do

View File

@@ -101,7 +101,7 @@ feature 'Admin budget investments' do
expect(page).to have_link("Change name") expect(page).to have_link("Change name")
expect(page).to have_link("Plant trees") expect(page).to have_link("Plant trees")
select "Parks: Central Park", from: "heading_id" select "Central Park", from: "heading_id"
expect(page).not_to have_link("Realocate visitors") expect(page).not_to have_link("Realocate visitors")
expect(page).not_to have_link("Change name") expect(page).not_to have_link("Change name")
@@ -372,7 +372,7 @@ feature 'Admin budget investments' do
click_button 'Search' click_button 'Search'
expect(page).to have_content(@investment_1.title) expect(page).to have_content(@investment_1.title)
expect(page).to_not have_content(@investment_2.title) expect(page).not_to have_content(@investment_2.title)
end end
end end

View File

@@ -5,7 +5,7 @@ feature 'Admin budget phases' do
context 'Edit' do context 'Edit' do
before :each do before do
admin = create(:administrator) admin = create(:administrator)
login_as(admin.user) login_as(admin.user)
end end
@@ -13,8 +13,8 @@ feature 'Admin budget phases' do
scenario 'Update phase' do scenario 'Update phase' do
visit edit_admin_budget_budget_phase_path(budget, budget.current_phase) visit edit_admin_budget_budget_phase_path(budget, budget.current_phase)
fill_in 'start_date', with: DateTime.current + 1.days fill_in 'start_date', with: Date.current + 1.days
fill_in 'end_date', with: DateTime.current + 12.days fill_in 'end_date', with: Date.current + 12.days
fill_in 'budget_phase_summary', with: 'This is the summary of the phase.' fill_in 'budget_phase_summary', with: 'This is the summary of the phase.'
fill_in 'budget_phase_description', with: 'This is the description of the phase.' fill_in 'budget_phase_description', with: 'This is the description of the phase.'
uncheck 'budget_phase_enabled' uncheck 'budget_phase_enabled'
@@ -23,8 +23,8 @@ feature 'Admin budget phases' do
expect(page).to have_current_path(edit_admin_budget_path(budget)) expect(page).to have_current_path(edit_admin_budget_path(budget))
expect(page).to have_content 'Changes saved' expect(page).to have_content 'Changes saved'
expect(budget.current_phase.starts_at.to_date).to eq((DateTime.current + 1.days).to_date) expect(budget.current_phase.starts_at.to_date).to eq((Date.current + 1.days).to_date)
expect(budget.current_phase.ends_at.to_date).to eq((DateTime.current + 12.days).to_date) expect(budget.current_phase.ends_at.to_date).to eq((Date.current + 12.days).to_date)
expect(budget.current_phase.summary).to eq('This is the summary of the phase.') expect(budget.current_phase.summary).to eq('This is the summary of the phase.')
expect(budget.current_phase.description).to eq('This is the description of the phase.') expect(budget.current_phase.description).to eq('This is the description of the phase.')
expect(budget.current_phase.enabled).to be(false) expect(budget.current_phase.enabled).to be(false)

View File

@@ -191,16 +191,19 @@ feature 'Admin budgets' do
budget = create(:budget, phase: 'reviewing_ballots') budget = create(:budget, phase: 'reviewing_ballots')
group = create(:budget_group, budget: budget) group = create(:budget_group, budget: budget)
heading = create(:budget_heading, group: group, price: 4) heading = create(:budget_heading, group: group, price: 4)
unselected_investment = create(:budget_investment, :unselected, heading: heading, price: 1, ballot_lines_count: 3) unselected = create(:budget_investment, :unselected, heading: heading, price: 1,
winner_investment = create(:budget_investment, :winner, heading: heading, price: 3, ballot_lines_count: 2) ballot_lines_count: 3)
selected_investment = create(:budget_investment, :selected, heading: heading, price: 2, ballot_lines_count: 1) winner = create(:budget_investment, :winner, heading: heading, price: 3,
ballot_lines_count: 2)
selected = create(:budget_investment, :selected, heading: heading, price: 2,
ballot_lines_count: 1)
visit edit_admin_budget_path(budget) visit edit_admin_budget_path(budget)
click_link 'Calculate Winner Investments' click_link 'Calculate Winner Investments'
expect(page).to have_content 'Winners being calculated, it may take a minute.' expect(page).to have_content 'Winners being calculated, it may take a minute.'
expect(page).to have_content winner_investment.title expect(page).to have_content winner.title
expect(page).not_to have_content unselected_investment.title expect(page).not_to have_content unselected.title
expect(page).not_to have_content selected_investment.title expect(page).not_to have_content selected.title
end end
scenario 'For a finished Budget' do scenario 'For a finished Budget' do
@@ -270,7 +273,7 @@ feature 'Admin budgets' do
expect(page).not_to have_content 'This group has no assigned heading.' 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 'District 9 reconstruction'
expect(page).to have_content '6785' expect(page).to have_content '€6,785'
expect(page).to have_content '100500' expect(page).to have_content '100500'
end end
end end
@@ -293,7 +296,7 @@ feature 'Admin budgets' do
end end
expect(page).to have_content 'District 2' expect(page).to have_content 'District 2'
expect(page).to have_content '10000' expect(page).to have_content '10,000'
expect(page).to have_content '6000' expect(page).to have_content '6000'
end end

View File

@@ -6,65 +6,73 @@ feature 'Budgets' do
let(:level_two_user) { create(:user, :level_two) } let(:level_two_user) { create(:user, :level_two) }
context 'Index' do context 'Index' do
let(:budgets) { create_list(:budget, 3) }
let(:last_budget) { budgets.last }
scenario 'Show normal index with links' do scenario 'Show normal index with links' do
group1 = create(:budget_group, budget: last_budget) group1 = create(:budget_group, budget: budget)
group2 = create(:budget_group, budget: last_budget) group2 = create(:budget_group, budget: budget)
heading1 = create(:budget_heading, group: group1) heading1 = create(:budget_heading, group: group1)
heading2 = create(:budget_heading, group: group2) heading2 = create(:budget_heading, group: group2)
last_budget.update_attributes(phase: 'informing') budget.update_attributes(phase: 'informing')
visit budgets_path visit budgets_path
within("#budget_heading") do within("#budget_heading") do
expect(page).to have_content(last_budget.name) expect(page).to have_content(budget.name)
expect(page).to have_content(last_budget.description) expect(page).to have_content(budget.description)
expect(page).to have_content(I18n.t('budgets.phase.informing')) expect(page).to have_content('Actual phase')
expect(page).to have_link 'Help with participatory budgets' expect(page).to have_content('Informing')
expect(page).to have_link 'See all phases' expect(page).to have_link('Help with participatory budgets')
expect(page).to have_link('See all phases')
end end
expect(page).to have_content("Accepting projects") budget.update_attributes(phase: 'publishing_prices')
last_budget.update_attributes(phase: 'publishing_prices')
visit budgets_path visit budgets_path
within("#budget_heading") do within("#budget_heading") do
expect(page).to have_content(I18n.t('budgets.phase.publishing_prices')) expect(page).to have_content('Publishing projects prices')
end end
within('#budget_info') do within('#budget_info') do
expect(page).to have_content group1.name expect(page).to have_content(group1.name)
expect(page).to have_content group2.name expect(page).to have_content(group2.name)
expect(page).to have_content heading1.name expect(page).to have_content(heading1.name)
expect(page).to have_content last_budget.formatted_heading_price(heading1) expect(page).to have_content(budget.formatted_heading_price(heading1))
expect(page).to have_content heading2.name expect(page).to have_content(heading2.name)
expect(page).to have_content last_budget.formatted_heading_price(heading2) expect(page).to have_content(budget.formatted_heading_price(heading2))
end
expect(page).to have_content budgets.first.name expect(page).not_to have_content("#finished_budgets")
expect(page).to have_content budgets[2].name end
scenario 'Show finished budgets list' do
finished_budget_1 = create(:budget, :finished)
finished_budget_2 = create(:budget, :finished)
drafting_budget = create(:budget, :drafting)
visit budgets_path
within("#finished_budgets") do
expect(page).to have_content(finished_budget_1.name)
expect(page).to have_content(finished_budget_2.name)
expect(page).not_to have_content(budget.name)
expect(page).not_to have_content(drafting_budget.name)
end end
end end
scenario 'Show informing index without links' do scenario 'Show informing index without links' do
last_budget.update_attributes(phase: 'informing') budget.update_attributes(phase: 'informing')
group = create(:budget_group, budget: last_budget) group = create(:budget_group, budget: budget)
heading = create(:budget_heading, group: group) heading = create(:budget_heading, group: group, name: 'Health')
visit budgets_path visit budgets_path
within('#budget_info') do within('#budget_info') do
expect(page).not_to have_link "#{heading.name} €1,000,000" expect(page).not_to have_link("Health €1,000,000")
expect(page).to have_content "#{heading.name} €1,000,000" expect(page).to have_content("Health €1,000,000")
expect(page).not_to have_link "List of all investment projects" expect(page).not_to have_link("List of all investment projects")
expect(page).not_to have_link "List of all unfeasible investment projects" expect(page).not_to have_link("List of all unfeasible investment projects")
expect(page).not_to have_link "List of all investment projects not selected for balloting" expect(page).not_to have_link("List of all investment projects not selected for balloting")
expect(page).not_to have_css('div#map') expect(page).not_to have_css('div#map')
end end
@@ -74,42 +82,42 @@ feature 'Budgets' do
scenario 'Index shows only published phases' do scenario 'Index shows only published phases' do
budget.update(phase: :finished) budget.update(phase: :finished)
phases = budget.phases
phases.drafting.update(starts_at: '30-12-2017', ends_at: '31-12-2017', enabled: true,
description: 'Description of drafting phase',
summary: '<p>This is the summary for drafting phase</p>')
budget.phases.drafting.update(starts_at: '30-12-2017', ends_at: '31-12-2017', enabled: true, phases.accepting.update(starts_at: '01-01-2018', ends_at: '10-01-2018', enabled: true,
description: 'Description of drafting phase', description: 'Description of accepting phase',
summary: '<p>This is the summary for drafting phase</p>') summary: 'This is the summary for accepting phase')
budget.phases.accepting.update(starts_at: '01-01-2018', ends_at: '10-01-2018', enabled: true, phases.reviewing.update(starts_at: '11-01-2018', ends_at: '20-01-2018', enabled: false,
description: 'Description of accepting phase', description: 'Description of reviewing phase',
summary: 'This is the summary for accepting phase') summary: 'This is the summary for reviewing phase')
budget.phases.reviewing.update(starts_at: '11-01-2018', ends_at: '20-01-2018', enabled: false, phases.selecting.update(starts_at: '21-01-2018', ends_at: '01-02-2018', enabled: true,
description: 'Description of reviewing phase', description: 'Description of selecting phase',
summary: 'This is the summary for reviewing phase') summary: 'This is the summary for selecting phase')
budget.phases.selecting.update(starts_at: '21-01-2018', ends_at: '01-02-2018', enabled: true, phases.valuating.update(starts_at: '10-02-2018', ends_at: '20-02-2018', enabled: false,
description: 'Description of selecting phase', description: 'Description of valuating phase',
summary: 'This is the summary for selecting phase') summary: 'This is the summary for valuating phase')
budget.phases.valuating.update(starts_at: '10-02-2018', ends_at: '20-02-2018', enabled: false, phases.publishing_prices.update(starts_at: '21-02-2018', ends_at: '01-03-2018', enabled: false,
description: 'Description of valuating phase', description: 'Description of publishing prices phase',
summary: 'This is the summary for valuating phase') summary: 'This is the summary for publishing_prices phase')
budget.phases.publishing_prices.update(starts_at: '21-02-2018', ends_at: '01-03-2018', enabled: false, phases.balloting.update(starts_at: '02-03-2018', ends_at: '10-03-2018', enabled: true,
description: 'Description of publishing prices phase', description: 'Description of balloting phase',
summary: 'This is the summary for publishing_prices phase') summary: 'This is the summary for balloting phase')
budget.phases.balloting.update(starts_at: '02-03-2018', ends_at: '10-03-2018', enabled: true, phases.reviewing_ballots.update(starts_at: '11-03-2018', ends_at: '20-03-2018', enabled: false,
description: 'Description of balloting phase', description: 'Description of reviewing ballots phase',
summary: 'This is the summary for balloting phase') summary: 'This is the summary for reviewing_ballots phase')
budget.phases.reviewing_ballots.update(starts_at: '11-03-2018', ends_at: '20-03-2018', enabled: false, phases.finished.update(starts_at: '21-03-2018', ends_at: '30-03-2018', enabled: true,
description: 'Description of reviewing ballots phase', description: 'Description of finished phase',
summary: 'This is the summary for reviewing_ballots phase') summary: 'This is the summary for finished phase')
budget.phases.finished.update(starts_at: '21-03-2018', ends_at: '30-03-2018', enabled: true,
description: 'Description of finished phase',
summary: 'This is the summary for finished phase')
visit budgets_path visit budgets_path
@@ -199,25 +207,11 @@ feature 'Budgets' do
end end
context "Listed" do context "Listed" do
scenario "Not listed to guest users at the public budgets list" do scenario "Not listed at public budgets list" do
visit budgets_path visit budgets_path
expect(page).not_to have_content(budget.name) expect(page).not_to have_content(budget.name)
end end
scenario "Not listed to logged users at the public budgets list" do
login_as(level_two_user)
visit budgets_path
expect(page).not_to have_content(budget.name)
end
scenario "Is listed to admins at the public budgets list" do
login_as(admin)
visit budgets_path
expect(page).to have_content(budget.name)
end
end end
context "Shown" do context "Shown" do
@@ -269,7 +263,7 @@ feature 'Budgets' do
scenario "user not logged in" do scenario "user not logged in" do
visit budget_path(budget) visit budget_path(budget)
expect(page).to have_content "To create a new budget investment you must sign in or sign up." expect(page).to have_content "To create a new budget investment you must sign in or sign up"
end end
end end

View File

@@ -609,7 +609,7 @@ feature 'Budget Investments' do
login_as(author) login_as(author)
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select 'Health: More hospitals', from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'I am a bot' fill_in 'budget_investment_title', with: 'I am a bot'
fill_in 'budget_investment_subtitle', with: 'This is the honeypot' fill_in 'budget_investment_subtitle', with: 'This is the honeypot'
fill_in 'budget_investment_description', with: 'This is the description' fill_in 'budget_investment_description', with: 'This is the description'
@@ -628,7 +628,7 @@ feature 'Budget Investments' do
login_as(author) login_as(author)
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select 'Health: More hospitals', from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'I am a bot' fill_in 'budget_investment_title', with: 'I am a bot'
fill_in 'budget_investment_description', with: 'This is the description' fill_in 'budget_investment_description', with: 'This is the description'
check 'budget_investment_terms_of_service' check 'budget_investment_terms_of_service'
@@ -644,7 +644,7 @@ feature 'Budget Investments' do
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select 'Health: More hospitals', from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds'
fill_in 'budget_investment_location', with: 'City center' fill_in 'budget_investment_location', with: 'City center'
@@ -735,6 +735,22 @@ feature 'Budget Investments' do
expect(page).not_to have_content('My ballot') expect(page).not_to have_content('My ballot')
end end
end end
scenario "Heading options are correctly ordered" do
city_group = create(:budget_group, name: "Toda la ciudad", budget: budget)
create(:budget_heading, name: "Toda la ciudad", price: 333333, group: city_group)
create(:budget_heading, name: "More health professionals", price: 999999, group: group)
login_as(author)
visit new_budget_investment_path(budget_id: budget.id)
select_options = find('#budget_investment_heading_id').all('option').collect(&:text)
expect(select_options.first).to eq('')
expect(select_options.second).to eq('Health: More health professionals')
expect(select_options.third).to eq('Health: More hospitals')
expect(select_options.fourth).to eq('Toda la ciudad')
end
end end
scenario "Show" do scenario "Show" do
@@ -1210,13 +1226,13 @@ feature 'Budget Investments' do
within("#budget_group_#{global_group.id}") do within("#budget_group_#{global_group.id}") do
expect(page).to have_content sp1.title expect(page).to have_content sp1.title
expect(page).to have_content sp1.price expect(page).to have_content "#{sp1.price}"
expect(page).to have_content sp2.title expect(page).to have_content sp2.title
expect(page).to have_content sp2.price expect(page).to have_content "#{sp2.price}"
expect(page).not_to have_content sp3.title expect(page).not_to have_content sp3.title
expect(page).not_to have_content sp3.price expect(page).not_to have_content "#{sp3.price}"
end end
within("#budget_group_#{group.id}") do within("#budget_group_#{group.id}") do

View File

@@ -7,16 +7,19 @@ feature 'Commenting Budget::Investments' do
scenario 'Index' do scenario 'Index' do
3.times { create(:comment, commentable: investment) } 3.times { create(:comment, commentable: investment) }
valuation_comment = create(:comment, :valuation, commentable: investment, subject: 'Not viable')
visit budget_investment_path(investment.budget, investment) visit budget_investment_path(investment.budget, investment)
expect(page).to have_css('.comment', count: 3) expect(page).to have_css('.comment', count: 3)
expect(page).not_to have_content('Not viable')
comment = Comment.last within("#comments") do
within first('.comment') do Comment.not_valuations.last(3).each do |comment|
expect(page).to have_content comment.user.name expect(page).to have_content comment.user.name
expect(page).to have_content I18n.l(comment.created_at, format: :datetime) expect(page).to have_content I18n.l(comment.created_at, format: :datetime)
expect(page).to have_content comment.body expect(page).to have_content comment.body
end
end end
end end
@@ -24,6 +27,7 @@ feature 'Commenting Budget::Investments' do
parent_comment = create(:comment, commentable: investment) parent_comment = create(:comment, commentable: investment)
first_child = create(:comment, commentable: investment, parent: parent_comment) first_child = create(:comment, commentable: investment, parent: parent_comment)
second_child = create(:comment, commentable: investment, parent: parent_comment) second_child = create(:comment, commentable: investment, parent: parent_comment)
valuation_comment = create(:comment, :valuation, commentable: investment, subject: 'Not viable')
visit comment_path(parent_comment) visit comment_path(parent_comment)
@@ -31,6 +35,7 @@ feature 'Commenting Budget::Investments' do
expect(page).to have_content parent_comment.body expect(page).to have_content parent_comment.body
expect(page).to have_content first_child.body expect(page).to have_content first_child.body
expect(page).to have_content second_child.body expect(page).to have_content second_child.body
expect(page).not_to have_content('Not viable')
expect(page).to have_link "Go back to #{investment.title}", href: budget_investment_path(investment.budget, investment) expect(page).to have_link "Go back to #{investment.title}", href: budget_investment_path(investment.budget, investment)

View File

@@ -0,0 +1,300 @@
require 'rails_helper'
feature 'Internal valuation comments on Budget::Investments' do
let(:user) { create(:user) }
let(:valuator_user) { create(:valuator).user }
let(:admin_user) { create(:administrator).user }
let(:budget) { create(:budget, :valuating) }
let(:investment) { create(:budget_investment, budget: budget) }
background do
Setting['feature.budgets'] = true
investment.valuators << valuator_user.valuator
login_as(valuator_user)
end
after do
Setting['feature.budgets'] = nil
end
context 'Show valuation comments' do
context 'Show valuation comments without public comments' do
background do
public_comment = create(:comment, commentable: investment, body: 'Public comment')
create(:comment, commentable: investment, author: valuator_user,
body: 'Public valuator comment')
create(:comment, commentable: investment, author: admin_user, parent: public_comment)
valuator_valuation = create(:comment, :valuation, commentable: investment,
author: valuator_user,
body: 'Valuator Valuation')
create(:comment, :valuation, commentable: investment, author: admin_user,
body: 'Admin Valuation')
admin_response = create(:comment, :valuation, commentable: investment, author: admin_user,
body: 'Admin Valuation response',
parent: valuator_valuation)
create(:comment, :valuation, commentable: investment, author: admin_user,
body: 'Valuator Valuation response', parent: admin_response)
end
scenario 'Valuation Show page without public comments' do
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content('Comment as admin')
expect(page).not_to have_content('Public comment')
expect(page).not_to have_content('Public valuator comment')
expect(page).to have_content('Leave your comment')
expect(page).to have_content('Valuator Valuation')
expect(page).to have_content('Admin Valuation')
expect(page).to have_content('Admin Valuation response')
expect(page).to have_content('Valuator Valuation response')
end
scenario 'Valuation Edit page without public comments' do
visit edit_valuation_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content('Comment as admin')
expect(page).not_to have_content('Public comment')
expect(page).not_to have_content('Public valuator comment')
expect(page).to have_content('Leave your comment')
expect(page).to have_content('Valuator Valuation')
expect(page).to have_content('Admin Valuation')
expect(page).to have_content('Admin Valuation response')
expect(page).to have_content('Valuator Valuation response')
end
end
scenario 'Collapsable comments', :js do
parent_comment = create(:comment, :valuation, author: valuator_user, body: "Main comment",
commentable: investment)
child_comment = create(:comment, :valuation, author: valuator_user, body: "First child",
commentable: investment, parent: parent_comment)
grandchild_comment = create(:comment, :valuation, author: valuator_user, parent: child_comment,
body: "Last child", commentable: investment)
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).to have_css('.comment', count: 3)
find("#comment_#{child_comment.id}_children_arrow").trigger('click')
expect(page).to have_css('.comment', count: 2)
expect(page).not_to have_content grandchild_comment.body
find("#comment_#{child_comment.id}_children_arrow").trigger('click')
expect(page).to have_css('.comment', count: 3)
expect(page).to have_content grandchild_comment.body
find("#comment_#{parent_comment.id}_children_arrow").trigger('click')
expect(page).to have_css('.comment', count: 1)
expect(page).not_to have_content child_comment.body
expect(page).not_to have_content grandchild_comment.body
end
scenario 'Comment order' do
create(:comment, :valuation, commentable: investment,
author: valuator_user,
body: 'Valuator Valuation',
created_at: Time.current - 1)
admin_valuation = create(:comment, :valuation, commentable: investment,
author: admin_user,
body: 'Admin Valuation',
created_at: Time.current - 2)
visit valuation_budget_budget_investment_path(budget, investment)
expect(admin_valuation.body).to appear_before('Valuator Valuation')
end
scenario 'Turns links into html links' do
create(:comment, :valuation, author: admin_user, commentable: investment,
body: 'Check http://rubyonrails.org/')
visit valuation_budget_budget_investment_path(budget, investment)
within first('.comment') do
expect(page).to have_content('Check http://rubyonrails.org/')
expect(page).to have_link('http://rubyonrails.org/', href: 'http://rubyonrails.org/')
expect(find_link('http://rubyonrails.org/')[:rel]).to eq('nofollow')
expect(find_link('http://rubyonrails.org/')[:target]).to eq('_blank')
end
end
scenario 'Sanitizes comment body for security' do
comment_with_js = "<script>alert('hola')</script> <a href=\"javascript:alert('sorpresa!')\">"\
"click me<a/> http://www.url.com"
create(:comment, :valuation, author: admin_user, commentable: investment,
body: comment_with_js)
visit valuation_budget_budget_investment_path(budget, investment)
within first('.comment') do
expect(page).to have_content("click me http://www.url.com")
expect(page).to have_link('http://www.url.com', href: 'http://www.url.com')
expect(page).not_to have_link('click me')
end
end
scenario 'Paginated comments' do
per_page = 10
(per_page + 2).times do
create(:comment, :valuation, commentable: investment, author: valuator_user)
end
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).to have_css('.comment', count: per_page)
within("ul.pagination") do
expect(page).to have_content("1")
expect(page).to have_content("2")
expect(page).not_to have_content("3")
click_link "Next", exact: false
end
expect(page).to have_css('.comment', count: 2)
end
end
context 'Valuation comment creation' do
scenario 'Normal users cannot create valuation comments altering public comments form', :js do
logout
login_as(user)
visit budget_investment_path(investment.budget, investment)
fill_in "comment-body-budget_investment_#{investment.id}", with: 'HACKERMAN IS HERE'
find(:xpath, "//input[@id='comment_valuation']", visible: false).set('true')
click_button 'Publish comment'
visit budget_investment_path(investment.budget, investment)
expect(page).not_to have_content('HACKERMAN IS HERE')
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).not_to have_content('HACKERMAN IS HERE')
end
scenario 'Create comment', :js do
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "comment-body-budget_investment_#{investment.id}", with: 'Have you thought about...?'
click_button 'Publish comment'
within "#comments" do
expect(page).to have_content 'Have you thought about...?'
end
end
scenario 'Errors on create without comment text', :js do
visit valuation_budget_budget_investment_path(budget, investment)
click_button 'Publish comment'
expect(page).to have_content "Can't be blank"
end
scenario 'Reply to existing comment', :js do
comment = create(:comment, :valuation, author: admin_user, commentable: investment)
login_as(valuator_user)
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in "comment-body-comment_#{comment.id}", with: 'It will be done next week.'
click_button 'Publish reply'
end
within "#comment_#{comment.id}" do
expect(page).to have_content 'It will be done next week.'
end
expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
end
scenario 'Errors on reply without comment text', :js do
comment = create(:comment, :valuation, author: admin_user, commentable: investment)
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
click_button 'Publish reply'
expect(page).to have_content "Can't be blank"
end
end
scenario "Multiple nested replies", :js do
parent = create(:comment, :valuation, author: valuator_user, commentable: investment)
7.times do
create(:comment, :valuation, author: admin_user, commentable: investment, parent: parent)
parent = parent.children.first
end
visit valuation_budget_budget_investment_path(budget, investment)
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
expect(page).to have_no_css('.comment-votes')
expect(page).to have_no_css('.js-flag-actions')
end
end
scenario "Erasing a comment's author" do
comment = create(:comment, :valuation, author: valuator_user, commentable: investment,
body: "this should be visible")
comment.user.erase
visit valuation_budget_budget_investment_path(budget, investment)
within "#comment_#{comment.id}" do
expect(page).to have_content('User deleted')
expect(page).to have_content('this should be visible')
end
end
feature "Administrators" do
scenario "can create valuation comment as an administrator", :js do
login_as(admin_user)
visit valuation_budget_budget_investment_path(budget, investment)
fill_in "comment-body-budget_investment_#{investment.id}", with: "I am your Admin!"
check "comment-as-administrator-budget_investment_#{investment.id}"
click_button "Publish comment"
within "#comments" do
expect(page).to have_content "I am your Admin!"
expect(page).to have_content "Administrator ##{admin_user.administrator.id}"
expect(page).to have_css "div.is-admin"
expect(page).to have_css "img.admin-avatar"
end
end
scenario "can create valuation reply as an administrator", :js do
comment = create(:comment, :valuation, author: valuator_user, commentable: investment)
login_as(admin_user)
visit valuation_budget_budget_investment_path(budget, investment)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in "comment-body-comment_#{comment.id}", with: "Top of the world!"
check "comment-as-administrator-comment_#{comment.id}"
click_button 'Publish reply'
end
within "#comment_#{comment.id}" do
expect(page).to have_content "Top of the world!"
expect(page).to have_content "Administrator ##{admin_user.administrator.id}"
expect(page).to have_css "div.is-admin"
expect(page).to have_css "img.admin-avatar"
end
expect(page).not_to have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
end
end
end

View File

@@ -366,7 +366,7 @@ feature 'Emails' do
login_as(author) login_as(author)
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a hospital' fill_in 'budget_investment_title', with: 'Build a hospital'
fill_in 'budget_investment_description', with: 'We have lots of people that require medical attention' fill_in 'budget_investment_description', with: 'We have lots of people that require medical attention'
check 'budget_investment_terms_of_service' check 'budget_investment_terms_of_service'

View File

@@ -29,7 +29,7 @@ feature 'Budget Investments' do
expect(page).to have_content user.document_number expect(page).to have_content user.document_number
end end
select "Whole city: Health", from: 'budget_investment_heading_id' select "Health", from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a park in my neighborhood' fill_in 'budget_investment_title', with: 'Build a park in my neighborhood'
fill_in 'budget_investment_description', with: 'There is no parks here...' fill_in 'budget_investment_description', with: 'There is no parks here...'
fill_in 'budget_investment_location', with: 'City center' fill_in 'budget_investment_location', with: 'City center'

View File

@@ -80,7 +80,7 @@ feature "Custom Pages" do
locale: "en" locale: "en"
) )
visit more_info_path visit help_path
expect(page).to have_content("Another custom page") expect(page).to have_content("Another custom page")
end end
@@ -93,7 +93,7 @@ feature "Custom Pages" do
locale: "en" locale: "en"
) )
visit more_info_path visit help_path
expect(page).not_to have_content("Another custom page") expect(page).not_to have_content("Another custom page")
@@ -112,7 +112,7 @@ feature "Custom Pages" do
locale: "fr" locale: "fr"
) )
visit more_info_path visit help_path
expect(page).not_to have_content("Ce texte est en français") expect(page).not_to have_content("Ce texte est en français")

View File

@@ -65,7 +65,7 @@ feature 'Tags' do
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds'
check 'budget_investment_terms_of_service' check 'budget_investment_terms_of_service'
@@ -84,7 +84,7 @@ feature 'Tags' do
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in_ckeditor 'budget_investment_description', with: 'If I had a gym near my place I could go do Zumba' fill_in_ckeditor 'budget_investment_description', with: 'If I had a gym near my place I could go do Zumba'
check 'budget_investment_terms_of_service' check 'budget_investment_terms_of_service'
@@ -100,12 +100,62 @@ feature 'Tags' do
end end
end end
scenario "Turbolinks sanity check from budget's show", :js do
login_as(author)
education = create(:tag, name: 'Education', kind: 'category')
health = create(:tag, name: 'Health', kind: 'category')
visit budget_path(budget)
click_link "Create a budget investment"
select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in_ckeditor 'budget_investment_description', with: 'If I had a gym near my place I could go do Zumba'
check 'budget_investment_terms_of_service'
find('.js-add-tag-link', text: 'Education').click
click_button 'Create Investment'
expect(page).to have_content 'Investment created successfully.'
within "#tags_budget_investment_#{Budget::Investment.last.id}" do
expect(page).to have_content 'Education'
expect(page).not_to have_content 'Health'
end
end
scenario "Turbolinks sanity check from budget heading's show", :js do
login_as(author)
education = create(:tag, name: 'Education', kind: 'category')
health = create(:tag, name: 'Health', kind: 'category')
visit budget_investments_path(budget, heading_id: heading.id)
click_link "Create a budget investment"
select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in_ckeditor 'budget_investment_description', with: 'If I had a gym near my place I could go do Zumba'
check 'budget_investment_terms_of_service'
find('.js-add-tag-link', text: 'Education').click
click_button 'Create Investment'
expect(page).to have_content 'Investment created successfully.'
within "#tags_budget_investment_#{Budget::Investment.last.id}" do
expect(page).to have_content 'Education'
expect(page).not_to have_content 'Health'
end
end
scenario 'Create with too many tags' do scenario 'Create with too many tags' do
login_as(author) login_as(author)
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds'
check 'budget_investment_terms_of_service' check 'budget_investment_terms_of_service'
@@ -123,7 +173,7 @@ feature 'Tags' do
visit new_budget_investment_path(budget_id: budget.id) visit new_budget_investment_path(budget_id: budget.id)
select "#{group.name}: #{heading.name}", from: 'budget_investment_heading_id' select heading.name, from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a skyscraper' fill_in 'budget_investment_title', with: 'Build a skyscraper'
fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds' fill_in 'budget_investment_description', with: 'I want to live in a high tower over the clouds'
check 'budget_investment_terms_of_service' check 'budget_investment_terms_of_service'

View File

@@ -16,7 +16,6 @@ feature 'Valuation budget investments' do
end end
scenario 'Display link to valuation section' do scenario 'Display link to valuation section' do
Setting['feature.budgets'] = true
visit root_path visit root_path
expect(page).to have_link "Valuation", href: valuation_root_path expect(page).to have_link "Valuation", href: valuation_root_path
end end

View File

@@ -3,96 +3,88 @@ require 'rails_helper'
feature 'Valuation' do feature 'Valuation' do
let(:user) { create(:user) } let(:user) { create(:user) }
background do context 'Access' do
Setting['feature.spending_proposals'] = true scenario 'Access as regular user is not authorized' do
Setting['feature.spending_proposal_features.voting_allowed'] = true login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as moderator is not authorized' do
create(:moderator, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as manager is not authorized' do
create(:manager, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as poll officer is not authorized' do
create(:poll_officer, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as a valuator is authorized' do
create(:valuator, user: user)
create(:budget)
login_as(user)
visit root_path
expect(page).to have_link("Valuation")
click_on "Valuation"
expect(page).to have_current_path(valuation_root_path)
expect(page).not_to have_content "You do not have permission to access this page"
end
scenario 'Access as an administrator is authorized' do
create(:administrator, user: user)
create(:budget)
login_as(user)
visit root_path
expect(page).to have_link("Valuation")
click_on "Valuation"
expect(page).to have_current_path(valuation_root_path)
expect(page).not_to have_content "You do not have permission to access this page"
end
end end
after do scenario 'Valuation access links' do
Setting['feature.spending_proposals'] = nil
Setting['feature.spending_proposal_features.voting_allowed'] = nil
end
scenario 'Access as regular user is not authorized' do
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as moderator is not authorized' do
create(:moderator, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as manager is not authorized' do
create(:manager, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as poll officer is not authorized' do
create(:poll_officer, user: user)
login_as(user)
visit root_path
expect(page).not_to have_link("Valuation")
visit valuation_root_path
expect(page).not_to have_current_path(valuation_root_path)
expect(page).to have_current_path(root_path)
expect(page).to have_content "You do not have permission to access this page"
end
scenario 'Access as a valuator is authorized' do
create(:valuator, user: user)
create(:budget)
login_as(user)
visit root_path
expect(page).to have_link("Valuation")
click_on "Valuation"
expect(page).to have_current_path(valuation_root_path)
expect(page).not_to have_content "You do not have permission to access this page"
end
scenario 'Access as an administrator is authorized' do
create(:administrator, user: user)
create(:budget)
login_as(user)
visit root_path
expect(page).to have_link("Valuation")
click_on "Valuation"
expect(page).to have_current_path(valuation_root_path)
expect(page).not_to have_content "You do not have permission to access this page"
end
scenario "Valuation access links" do
create(:valuator, user: user) create(:valuator, user: user)
create(:budget) create(:budget)

View File

@@ -30,7 +30,7 @@ feature 'rake sitemap:create' do
# Static pages # Static pages
expect(sitemap).to include(faq_path) expect(sitemap).to include(faq_path)
expect(sitemap).to include(more_info_path) expect(sitemap).to include(help_path)
expect(sitemap).to include(how_to_use_path) expect(sitemap).to include(how_to_use_path)
expect(sitemap).to include(page_path(id: 'general_terms')) expect(sitemap).to include(page_path(id: 'general_terms'))

View File

@@ -192,7 +192,7 @@ describe Budget do
describe "#generate_phases" do describe "#generate_phases" do
let(:drafting_phase) { budget.phases.drafting } let(:drafting_phase) { budget.phases.drafting }
let(:informing_phase) { budget.phases.informing } let(:informing_phase) { budget.phases.informing }
let(:accepting_phase) { budget.phases.accepting } let(:accepting_phase) { budget.phases.accepting }
let(:reviewing_phase) { budget.phases.reviewing } let(:reviewing_phase) { budget.phases.reviewing }
let(:selecting_phase) { budget.phases.selecting } let(:selecting_phase) { budget.phases.selecting }

View File

@@ -187,5 +187,11 @@ describe Comment do
expect(described_class.public_for_api).not_to include(comment) expect(described_class.public_for_api).not_to include(comment)
end end
it "does not return internal valuation comments" do
valuation_comment = create(:comment, :valuation)
expect(described_class.public_for_api).not_to include(valuation_comment)
end
end end
end end