Merge branch 'master' into voting-proposals
Conflicts: app/models/proposal.rb app/views/proposals/_proposal.html.erb app/views/proposals/index.html.erb app/views/proposals/show.html.erb spec/support/common_actions.rb
This commit is contained in:
@@ -24,6 +24,8 @@ Frontend tools used include [SCSS](http://sass-lang.com/) over [Foundation](http
|
|||||||
|
|
||||||
## Configuration for development and test environments
|
## Configuration for development and test environments
|
||||||
|
|
||||||
|
**NOTE**: For more detailed instructions check the [docs](https://github.com/consul/consul/tree/master/doc/en/dev_test_setup.md)
|
||||||
|
|
||||||
Prerequisites: install git, Ruby 2.2.3, bundler gem, ghostscript and PostgreSQL (>=9.4).
|
Prerequisites: install git, Ruby 2.2.3, bundler gem, ghostscript and PostgreSQL (>=9.4).
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ Las herramientas utilizadas para el frontend no están cerradas aún. Los estilo
|
|||||||
|
|
||||||
## Configuración para desarrollo y tests
|
## Configuración para desarrollo y tests
|
||||||
|
|
||||||
|
**NOTA**: para unas instrucciones más detalladas consulta la [documentación](https://github.com/consul/consul/tree/master/doc/es/dev_test_setup.md)
|
||||||
|
|
||||||
Prerequisitos: tener instalado git, Ruby 2.2.3, la gema `bundler`, ghostscript y PostgreSQL (9.4 o superior).
|
Prerequisitos: tener instalado git, Ruby 2.2.3, la gema `bundler`, ghostscript y PostgreSQL (9.4 o superior).
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -270,6 +270,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
@include supports;
|
||||||
|
background: none;
|
||||||
|
border-top: 0;
|
||||||
|
|
||||||
|
@include breakpoint(medium) {
|
||||||
|
border-left: 1px solid $border;
|
||||||
|
margin: $line-height rem-calc(-25) 0 rem-calc(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: $small-font-size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 02. New participation
|
// 02. New participation
|
||||||
// ---------------------
|
// ---------------------
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class ProposalsController < ApplicationController
|
|||||||
|
|
||||||
invisible_captcha only: [:create, :update], honeypot: :subtitle
|
invisible_captcha only: [:create, :update], honeypot: :subtitle
|
||||||
|
|
||||||
has_orders %w{hot_score confidence_score created_at relevance}, only: :index
|
has_orders %w{hot_score confidence_score created_at relevance archival_date}, only: :index
|
||||||
has_orders %w{most_voted newest oldest}, only: :show
|
has_orders %w{most_voted newest oldest}, only: :show
|
||||||
|
|
||||||
load_and_authorize_resource
|
load_and_authorize_resource
|
||||||
@@ -26,6 +26,7 @@ class ProposalsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def index_customization
|
def index_customization
|
||||||
|
discard_archived
|
||||||
load_retired
|
load_retired
|
||||||
load_proposal_ballots
|
load_proposal_ballots
|
||||||
load_featured unless @proposal_successfull_exists
|
load_featured unless @proposal_successfull_exists
|
||||||
@@ -81,6 +82,10 @@ class ProposalsController < ApplicationController
|
|||||||
@featured_proposals_votes = current_user ? current_user.proposal_votes(proposals) : {}
|
@featured_proposals_votes = current_user ? current_user.proposal_votes(proposals) : {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def discard_archived
|
||||||
|
@resources = @resources.not_archived unless @current_order == "archival_date"
|
||||||
|
end
|
||||||
|
|
||||||
def load_retired
|
def load_retired
|
||||||
if params[:retired].present?
|
if params[:retired].present?
|
||||||
@resources = @resources.retired
|
@resources = @resources.retired
|
||||||
@@ -91,7 +96,7 @@ class ProposalsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def load_featured
|
def load_featured
|
||||||
@featured_proposals = Proposal.all.sort_by_confidence_score.limit(3) if (!@advanced_search_terms && @search_terms.blank? && @tag_filter.blank? && params[:retired].blank?)
|
@featured_proposals = Proposal.not_archived.sort_by_confidence_score.limit(3) if (!@advanced_search_terms && @search_terms.blank? && @tag_filter.blank? && params[:retired].blank?)
|
||||||
if @featured_proposals.present?
|
if @featured_proposals.present?
|
||||||
set_featured_proposal_votes(@featured_proposals)
|
set_featured_proposal_votes(@featured_proposals)
|
||||||
@resources = @resources.where('proposals.id NOT IN (?)', @featured_proposals.map(&:id))
|
@resources = @resources.where('proposals.id NOT IN (?)', @featured_proposals.map(&:id))
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ class Proposal < ActiveRecord::Base
|
|||||||
scope :sort_by_random, -> { reorder("RANDOM()") }
|
scope :sort_by_random, -> { reorder("RANDOM()") }
|
||||||
scope :sort_by_relevance, -> { all }
|
scope :sort_by_relevance, -> { all }
|
||||||
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||||
|
scope :sort_by_archival_date, -> { archived.order(created_at: :desc) }
|
||||||
|
scope :archived, -> { where("proposals.created_at <= ?", Setting["months_to_archive_proposals"].to_i.months.ago)}
|
||||||
|
scope :not_archived, -> { where("proposals.created_at > ?", Setting["months_to_archive_proposals"].to_i.months.ago)}
|
||||||
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
|
scope :last_week, -> { where("proposals.created_at >= ?", 7.days.ago)}
|
||||||
scope :retired, -> { where.not(retired_at: nil) }
|
scope :retired, -> { where.not(retired_at: nil) }
|
||||||
scope :not_retired, -> { where(retired_at: nil) }
|
scope :not_retired, -> { where(retired_at: nil) }
|
||||||
@@ -120,7 +123,7 @@ class Proposal < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def register_vote(user, vote_value)
|
def register_vote(user, vote_value)
|
||||||
if votable_by?(user)
|
if votable_by?(user) && !archived?
|
||||||
vote_by(voter: user, vote: vote_value)
|
vote_by(voter: user, vote: vote_value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -160,6 +163,10 @@ class Proposal < ActiveRecord::Base
|
|||||||
total_votes >= Proposal.votes_needed_for_success
|
total_votes >= Proposal.votes_needed_for_success
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def archived?
|
||||||
|
self.created_at <= Setting["months_to_archive_proposals"].to_i.months.ago
|
||||||
|
end
|
||||||
|
|
||||||
def notifications
|
def notifications
|
||||||
proposal_notifications
|
proposal_notifications
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -7,7 +7,16 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<%= proposal.author.name %>
|
<%= proposal.author.name %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
•
|
•
|
||||||
|
|
||||||
|
<% if proposal.author.display_official_position_badge? %>
|
||||||
|
<span class="label round level-<%= proposal.author.official_level %>">
|
||||||
|
<%= proposal.author.official_position %>
|
||||||
|
</span>
|
||||||
|
•
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<strong><%= t("proposals.proposal.supports", count: proposal.total_votes) %></strong>
|
<strong><%= t("proposals.proposal.supports", count: proposal.total_votes) %></strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -59,6 +59,10 @@
|
|||||||
<%= t("proposal_ballots.successfull",
|
<%= t("proposal_ballots.successfull",
|
||||||
voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %>
|
voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %>
|
||||||
</p>
|
</p>
|
||||||
|
<% elsif proposal.archived? %>
|
||||||
|
<div class="message">
|
||||||
|
<strong><%= t("proposals.proposal.supports", count: proposal.total_votes) %></strong>
|
||||||
|
<p><%= t("proposals.proposal.archived") %></p>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
|
|||||||
@@ -54,8 +54,10 @@
|
|||||||
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button expanded' %>
|
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button expanded' %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= render partial: 'proposals/proposal', collection: @proposals %>
|
<div id="proposals-list">
|
||||||
<%= paginate @proposals %>
|
<%= render partial: 'proposals/proposal', collection: @proposals %>
|
||||||
|
<%= paginate @proposals %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="small-12 medium-3 column">
|
<div class="small-12 medium-3 column">
|
||||||
|
|||||||
@@ -108,6 +108,11 @@
|
|||||||
<%= t("proposal_ballots.successfull",
|
<%= t("proposal_ballots.successfull",
|
||||||
voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %>
|
voting: link_to(t("proposal_ballots.voting"), proposal_ballots_path)).html_safe %>
|
||||||
</p>
|
</p>
|
||||||
|
<% elsif @proposal.archived? %>
|
||||||
|
<p class="text-center">
|
||||||
|
<strong><%= t("proposals.proposal.supports", count: @proposal.total_votes) %></strong>
|
||||||
|
</p>
|
||||||
|
<p><%= t("proposals.proposal.archived") %></p>
|
||||||
<% else %>
|
<% else %>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<%= render 'votes',
|
<%= render 'votes',
|
||||||
@@ -115,7 +120,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="social-share" class="sidebar-divider"></div>
|
<div id="social-share" class="sidebar-divider"></div>
|
||||||
<h3><%= t("proposals.show.share") %></h3>
|
<h3><%= t("proposals.show.share") %></h3>
|
||||||
<div class="social-share-full">
|
<div class="social-share-full">
|
||||||
|
|||||||
23
bin/rails
23
bin/rails
@@ -1,8 +1,17 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
begin
|
# frozen_string_literal: true
|
||||||
load File.expand_path("../spring", __FILE__)
|
#
|
||||||
rescue LoadError
|
# This file was generated by Bundler.
|
||||||
end
|
#
|
||||||
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
# The application 'rails' is installed as part of a gem, and
|
||||||
require_relative '../config/boot'
|
# this file is here to facilitate running it.
|
||||||
require 'rails/commands'
|
#
|
||||||
|
|
||||||
|
require "pathname"
|
||||||
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||||
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
|
require "rubygems"
|
||||||
|
require "bundler/setup"
|
||||||
|
|
||||||
|
load Gem.bin_path("railties", "rails")
|
||||||
|
|||||||
23
bin/rake
23
bin/rake
@@ -1,8 +1,17 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
begin
|
# frozen_string_literal: true
|
||||||
load File.expand_path("../spring", __FILE__)
|
#
|
||||||
rescue LoadError
|
# This file was generated by Bundler.
|
||||||
end
|
#
|
||||||
require_relative '../config/boot'
|
# The application 'rake' is installed as part of a gem, and
|
||||||
require 'rake'
|
# this file is here to facilitate running it.
|
||||||
Rake.application.run
|
#
|
||||||
|
|
||||||
|
require "pathname"
|
||||||
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||||
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
|
require "rubygems"
|
||||||
|
require "bundler/setup"
|
||||||
|
|
||||||
|
load Gem.bin_path("rake", "rake")
|
||||||
|
|||||||
16
bin/rspec
16
bin/rspec
@@ -1,9 +1,5 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
begin
|
# frozen_string_literal: true
|
||||||
load File.expand_path('../spring', __FILE__)
|
|
||||||
rescue LoadError => e
|
|
||||||
raise unless e.message.include?('spring')
|
|
||||||
end
|
|
||||||
#
|
#
|
||||||
# This file was generated by Bundler.
|
# This file was generated by Bundler.
|
||||||
#
|
#
|
||||||
@@ -11,11 +7,11 @@ end
|
|||||||
# this file is here to facilitate running it.
|
# this file is here to facilitate running it.
|
||||||
#
|
#
|
||||||
|
|
||||||
require 'pathname'
|
require "pathname"
|
||||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||||
Pathname.new(__FILE__).realpath)
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
require 'rubygems'
|
require "rubygems"
|
||||||
require 'bundler/setup'
|
require "bundler/setup"
|
||||||
|
|
||||||
load Gem.bin_path('rspec-core', 'rspec')
|
load Gem.bin_path("rspec-core", "rspec")
|
||||||
|
|||||||
24
bin/spring
24
bin/spring
@@ -1,15 +1,17 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
# frozen_string_literal: true
|
||||||
|
#
|
||||||
|
# This file was generated by Bundler.
|
||||||
|
#
|
||||||
|
# The application 'spring' is installed as part of a gem, and
|
||||||
|
# this file is here to facilitate running it.
|
||||||
|
#
|
||||||
|
|
||||||
# This file loads spring without using Bundler, in order to be fast.
|
require "pathname"
|
||||||
# It gets overwritten when you run the `spring binstub` command.
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
||||||
|
Pathname.new(__FILE__).realpath)
|
||||||
|
|
||||||
unless defined?(Spring)
|
require "rubygems"
|
||||||
require 'rubygems'
|
require "bundler/setup"
|
||||||
require 'bundler'
|
|
||||||
|
|
||||||
if (match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m))
|
load Gem.bin_path("spring", "spring")
|
||||||
Gem.paths = { 'GEM_PATH' => [Bundler.bundle_path.to_s, *Gem.path].uniq }
|
|
||||||
gem 'spring', match[1]
|
|
||||||
require 'spring/binstub'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ en:
|
|||||||
hot_score: most active
|
hot_score: most active
|
||||||
most_commented: most commented
|
most_commented: most commented
|
||||||
relevance: relevance
|
relevance: relevance
|
||||||
|
archival_date: Archived
|
||||||
retired_proposals: Retired proposals
|
retired_proposals: Retired proposals
|
||||||
retired_proposals_link: "Proposals retired by the author"
|
retired_proposals_link: "Proposals retired by the author"
|
||||||
retired_links:
|
retired_links:
|
||||||
@@ -351,6 +352,7 @@ en:
|
|||||||
zero: No supports
|
zero: No supports
|
||||||
supports_necessary: "%{number} supports needed"
|
supports_necessary: "%{number} supports needed"
|
||||||
total_percent: 100%
|
total_percent: 100%
|
||||||
|
archived: "This proposal has been archived and can't collect supports."
|
||||||
show:
|
show:
|
||||||
author_deleted: User deleted
|
author_deleted: User deleted
|
||||||
code: 'Proposal code:'
|
code: 'Proposal code:'
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ es:
|
|||||||
hot_score: Más activas hoy
|
hot_score: Más activas hoy
|
||||||
most_commented: Más comentadas
|
most_commented: Más comentadas
|
||||||
relevance: Más relevantes
|
relevance: Más relevantes
|
||||||
|
archival_date: Archivadas
|
||||||
retired_proposals: Propuestas retiradas
|
retired_proposals: Propuestas retiradas
|
||||||
retired_proposals_link: "Propuestas retiradas por sus autores"
|
retired_proposals_link: "Propuestas retiradas por sus autores"
|
||||||
retired_links:
|
retired_links:
|
||||||
@@ -351,6 +352,7 @@ es:
|
|||||||
zero: Sin apoyos
|
zero: Sin apoyos
|
||||||
supports_necessary: "%{number} apoyos necesarios"
|
supports_necessary: "%{number} apoyos necesarios"
|
||||||
total_percent: 100%
|
total_percent: 100%
|
||||||
|
archived: "Esta propuesta ha sido archivada y ya no puede recoger apoyos."
|
||||||
show:
|
show:
|
||||||
author_deleted: Usuario eliminado
|
author_deleted: Usuario eliminado
|
||||||
code: 'Código de la propuesta:'
|
code: 'Código de la propuesta:'
|
||||||
|
|||||||
@@ -33,13 +33,13 @@ es:
|
|||||||
|
|
||||||
Tanto los hilos, como los comentarios podrán ser valorados por cualquiera, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son los temas más importantes en cada momento. Estos serán presentados en la portada del espacio, pudiendo por supuesto accederse a todos los demás temas en páginas posteriores, o usando otros criterios de ordenación (los temas con más comentarios, los más nuevos, los más controvertidos, etc.).
|
Tanto los hilos, como los comentarios podrán ser valorados por cualquiera, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son los temas más importantes en cada momento. Estos serán presentados en la portada del espacio, pudiendo por supuesto accederse a todos los demás temas en páginas posteriores, o usando otros criterios de ordenación (los temas con más comentarios, los más nuevos, los más controvertidos, etc.).
|
||||||
|
|
||||||
Cada uno de los trabajadores del Ayuntamiento tiene un usuario propio, que será resaltado como tal, permitiendo que participen en los debates al mismo nivel que todos los demás ciudadanos. Esto permitirá crear espacios de comunicación directos entre unos y otros, evitando los inconvenientes que implica la comunicación medidada, y respondiendo a un planteamiento claro por parte del nuevo gobierno por el cual el Ayuntamiento trabaja para la ciudadanía, y ante ella debe responder.
|
Cada uno de los trabajadores del Ayuntamiento tiene un usuario propio, que será resaltado como tal, permitiendo que participen en los debates al mismo nivel que todos los demás ciudadanos. Esto permitirá crear espacios de comunicación directos entre unos y otros, evitando los inconvenientes que implica la comunicación mediada, y respondiendo a un planteamiento claro por parte del nuevo gobierno por el cual el Ayuntamiento trabaja para la ciudadanía, y ante ella debe responder.
|
||||||
## <a id='i2'></a> I.I. Espacio de propuestas
|
## <a id='i2'></a> I.I. Espacio de propuestas
|
||||||
En este espacio, cualquier persona puede proponer una iniciativa con la intención de recabar los suficientes apoyos como para que la idea pase a ser consultada a toda la ciudadanía con caracter vinculante.
|
En este espacio, cualquier persona puede proponer una iniciativa con la intención de recabar los suficientes apoyos como para que la idea pase a ser consultada a toda la ciudadanía con carácter vinculante.
|
||||||
|
|
||||||
Las propuestas pueden ser apoyadas por ciudadanos empadronados que hayan verificado su cuenta en la plataforma de participación, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son las propuestas que merecen la pena ser llevadas a cabo.
|
Las propuestas pueden ser apoyadas por ciudadanos empadronados que hayan verificado su cuenta en la plataforma de participación, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son las propuestas que merecen la pena ser llevadas a cabo.
|
||||||
|
|
||||||
Una vez que una propuesta alcance una cantidad de apoyos equivalente al 2% del censo, automaticamente pasa a ser estudiada por un grupo de trabajo del Ayuntamiento y pasará a la siguiente fase de consulta popular, en la que la ciudadanía votará si se lleva a cabo o no. El plazo máximo para recabar los apoyos necesarios será de 12 meses.
|
Una vez que una propuesta alcance una cantidad de apoyos equivalente al 2% del censo, automáticamente pasa a ser estudiada por un grupo de trabajo del Ayuntamiento y pasará a la siguiente fase de consulta popular, en la que la ciudadanía votará si se lleva a cabo o no. El plazo máximo para recabar los apoyos necesarios será de 12 meses.
|
||||||
how_to_use:
|
how_to_use:
|
||||||
text: |-
|
text: |-
|
||||||
Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre.
|
Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ en:
|
|||||||
max_votes_for_debate_edit: "Number of votes from which a Debate can no longer be edited"
|
max_votes_for_debate_edit: "Number of votes from which a Debate can no longer be edited"
|
||||||
proposal_code_prefix: "Prefix for Proposal codes"
|
proposal_code_prefix: "Prefix for Proposal codes"
|
||||||
votes_for_proposal_success: "Number of votes necessary for approval of a Proposal"
|
votes_for_proposal_success: "Number of votes necessary for approval of a Proposal"
|
||||||
|
months_to_archive_proposals: "Months to archive Proposals"
|
||||||
email_domain_for_officials: "Email domain for public officials"
|
email_domain_for_officials: "Email domain for public officials"
|
||||||
per_page_code: "Code to be included on every page"
|
per_page_code: "Code to be included on every page"
|
||||||
feature:
|
feature:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ es:
|
|||||||
max_votes_for_debate_edit: "Número de votos en que un Debate deja de poderse editar"
|
max_votes_for_debate_edit: "Número de votos en que un Debate deja de poderse editar"
|
||||||
proposal_code_prefix: "Prefijo para los códigos de Propuestas"
|
proposal_code_prefix: "Prefijo para los códigos de Propuestas"
|
||||||
votes_for_proposal_success: "Número de votos necesarios para aprobar una Propuesta"
|
votes_for_proposal_success: "Número de votos necesarios para aprobar una Propuesta"
|
||||||
|
months_to_archive_proposals: "Meses para archivar las Propuestas"
|
||||||
email_domain_for_officials: "Dominio de email para cargos públicos"
|
email_domain_for_officials: "Dominio de email para cargos públicos"
|
||||||
per_page_code: "Código a incluir en cada página"
|
per_page_code: "Código a incluir en cada página"
|
||||||
feature:
|
feature:
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Setting.create(key: 'max_votes_for_debate_edit', value: '1000')
|
|||||||
Setting.create(key: 'max_votes_for_proposal_edit', value: '1000')
|
Setting.create(key: 'max_votes_for_proposal_edit', value: '1000')
|
||||||
Setting.create(key: 'proposal_code_prefix', value: 'MAD')
|
Setting.create(key: 'proposal_code_prefix', value: 'MAD')
|
||||||
Setting.create(key: 'votes_for_proposal_success', value: '100')
|
Setting.create(key: 'votes_for_proposal_success', value: '100')
|
||||||
|
Setting.create(key: 'months_to_archive_proposals', value: '12')
|
||||||
Setting.create(key: 'comments_body_max_length', value: '1000')
|
Setting.create(key: 'comments_body_max_length', value: '1000')
|
||||||
|
|
||||||
Setting.create(key: 'twitter_handle', value: '@consul_dev')
|
Setting.create(key: 'twitter_handle', value: '@consul_dev')
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ Setting["proposal_code_prefix"] = 'MAD'
|
|||||||
# Number of votes needed for proposal success
|
# Number of votes needed for proposal success
|
||||||
Setting["votes_for_proposal_success"] = 53726
|
Setting["votes_for_proposal_success"] = 53726
|
||||||
|
|
||||||
|
# Months to archive proposals
|
||||||
|
Setting["months_to_archive_proposals"] = 12
|
||||||
|
|
||||||
# Users with this email domain will automatically be marked as level 1 officials
|
# Users with this email domain will automatically be marked as level 1 officials
|
||||||
# Emails under the domain's subdomains will also be included
|
# Emails under the domain's subdomains will also be included
|
||||||
Setting["email_domain_for_officials"] = ''
|
Setting["email_domain_for_officials"] = ''
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Actualmente Consul soporta:
|
Actualmente Consul soporta:
|
||||||
|
|
||||||
* Registro y verificación de usuarios tanto en la misma aplicación como con distintos proveedores (Twitter, Facebook, Google)
|
* Registro y verificación de usuarios tanto en la misma aplicación como con distintos proveedores (Twitter, Facebook, Google).
|
||||||
* Distintos perfiles de usuario, tanto ciudadanos individuales como organizaciones.
|
* Distintos perfiles de usuario, tanto ciudadanos individuales como organizaciones.
|
||||||
* Distintos perfiles de administración, gestión y moderación.
|
* Distintos perfiles de administración, gestión y moderación.
|
||||||
* Espacio permanente de debates y propuestas.
|
* Espacio permanente de debates y propuestas.
|
||||||
@@ -11,7 +11,7 @@ Actualmente Consul soporta:
|
|||||||
|
|
||||||
# Usuario
|
# Usuario
|
||||||
|
|
||||||
Para registrar un usuario nuevo es posible hacerlo en la propia aplicación, dando un nombre de usuario (Nombre público que aparecerá en tus publicaciones), un correo electrónico y una contraseña con la que se accederá a la web. Se deben aceptar las condiciones de uso. El usuario debe confirmar su correo electrónico para poder iniciar sesión
|
Para registrar un usuario nuevo es posible hacerlo en la propia aplicación, dando un nombre de usuario (nombre público que aparecerá en tus publicaciones), un correo electrónico y una contraseña con la que se accederá a la web. Se deben aceptar las condiciones de uso. El usuario debe confirmar su correo electrónico para poder iniciar sesión.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -38,11 +38,11 @@ Para esta funcionalidad hace falta que el padrón municipal soporte la posibilid
|
|||||||
|
|
||||||
Dentro de su perfil cada usuario puede configurar si quiere mostrar públicamente su lista de actividades, así como las notificaciones que le enviará la aplicación a través de correo electrónico. Estas notificiaciones pueden ser:
|
Dentro de su perfil cada usuario puede configurar si quiere mostrar públicamente su lista de actividades, así como las notificaciones que le enviará la aplicación a través de correo electrónico. Estas notificiaciones pueden ser:
|
||||||
|
|
||||||
* Recibir un email cuando alguien comenta en sus propuestas o debates
|
* Recibir un email cuando alguien comenta en sus propuestas o debates.
|
||||||
* Recibir un email cuando alguien contesta a sus comentarios
|
* Recibir un email cuando alguien contesta a sus comentarios.
|
||||||
* Recibir emails con información interesante sobre la web
|
* Recibir emails con información interesante sobre la web.
|
||||||
* Recibir resumen de notificaciones sobre propuestas
|
* Recibir resumen de notificaciones sobre propuestas.
|
||||||
* Recibir emails con mensajes privados
|
* Recibir emails con mensajes privados.
|
||||||
|
|
||||||
# Paneles de administración, gestión y moderación
|
# Paneles de administración, gestión y moderación
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ Desde aquí puedes administrar el sistema, a través de las siguientes acciones:
|
|||||||
|
|
||||||
### Temas de debate
|
### Temas de debate
|
||||||
|
|
||||||
Los temas (también llamadas tags, o etiquetas) de debate son palabras que definen los usuarios al crear debates, para catalogarlos (ej: sanidad, movilidad, arganzuela, ...). Aquí se pueden eliminar temas inapropiados, o marcarlos para ser propuestos al crear debates (cada usuario puede definir los que quiera, pero se le sugieren algunos que nos parecen útiles como catalogación por defecto; aquí se puede cambiar cuáles se sugieren)
|
Los temas (también llamadas tags, o etiquetas) de debate son palabras que definen los usuarios al crear debates, para catalogarlos (ej: sanidad, movilidad, arganzuela, ...). Aquí se pueden eliminar temas inapropiados, o marcarlos para ser propuestos al crear debates (cada usuario puede definir los que quiera, pero se le sugieren algunos que nos parecen útiles como catalogación por defecto; aquí se puede cambiar cuáles se sugieren).
|
||||||
|
|
||||||
### Propuestas/Debates/Comentarios ocultos
|
### Propuestas/Debates/Comentarios ocultos
|
||||||
|
|
||||||
@@ -77,8 +77,6 @@ En la web hay dos tipos de usuarios: individuales y organizaciones. Cualquier pe
|
|||||||
|
|
||||||
En caso de que el proceso de verificación haya sido negativo, se pulsa el botón "Rechazar". Para editar alguno de los datos de la organización, se pulsa el botón "Editar".
|
En caso de que el proceso de verificación haya sido negativo, se pulsa el botón "Rechazar". Para editar alguno de los datos de la organización, se pulsa el botón "Editar".
|
||||||
|
|
||||||
En caso de que el proceso de verificación haya sido negativo, se pulsa el botón "Rechazar". Para editar alguno de los datos de la organización, se pulsa el botón "Editar".
|
|
||||||
|
|
||||||
Las organizaciones que no aparecen en la lista pueden ser encontradas para actuar sobre ellas por medio del buscador en la parte superior. Para facilitar la gestión, arriba encontramos un filtro con las secciones: "pendientes" (las organizaciones que todavía no han sido verificadas o rechazadas), "verificadas", "rechazadas" y "todas".
|
Las organizaciones que no aparecen en la lista pueden ser encontradas para actuar sobre ellas por medio del buscador en la parte superior. Para facilitar la gestión, arriba encontramos un filtro con las secciones: "pendientes" (las organizaciones que todavía no han sido verificadas o rechazadas), "verificadas", "rechazadas" y "todas".
|
||||||
|
|
||||||
Es recomendable revisar regularmente la sección "pendientes".
|
Es recomendable revisar regularmente la sección "pendientes".
|
||||||
@@ -89,7 +87,7 @@ En la web, los usuarios individuales pueden ser usuarios normales, o cargos púb
|
|||||||
|
|
||||||
### Moderadores
|
### Moderadores
|
||||||
|
|
||||||
Mediante el buscador de la parte superior se pueden buscar usuarios, para activarlos o desactivarlos como moderadores de la web. Los moderadores al acceder a la web con su usuario ven en la parte superior una nueva sección llamada "Moderar"
|
Mediante el buscador de la parte superior se pueden buscar usuarios, para activarlos o desactivarlos como moderadores de la web. Los moderadores al acceder a la web con su usuario ven en la parte superior una nueva sección llamada "Moderar".
|
||||||
|
|
||||||
### Actividad de moderadores
|
### Actividad de moderadores
|
||||||
|
|
||||||
@@ -116,13 +114,14 @@ Cuando un usuario marca en una Propuesta/Debate/Comentario la opción de "denunc
|
|||||||
A la derecha de cada elemento aparece una caja que podemos marcar para seleccionar todos los que queramos de la lista. Una vez seleccionados uno o varios, encontramos al final de la página tres botones para realizar acciones sobre ellos:
|
A la derecha de cada elemento aparece una caja que podemos marcar para seleccionar todos los que queramos de la lista. Una vez seleccionados uno o varios, encontramos al final de la página tres botones para realizar acciones sobre ellos:
|
||||||
|
|
||||||
* Ocultar: hará que esos elementos dejen de mostrarse en la web.
|
* Ocultar: hará que esos elementos dejen de mostrarse en la web.
|
||||||
* Bloquear autores: hará que el autor de ese elemento deje de poder acceder a la web, y que además todos las Propuestas/Debates/Comentarios de ese usuario dejen de mostrarse en la web.
|
* Bloquear autores: hará que el autor de ese elemento deje de poder acceder a la web, y que además todas las Propuestas/Debates/Comentarios de ese usuario dejen de mostrarse en la web.
|
||||||
* Marcar como revisados cuando consideramos que esos elementos no deben ser moderados, que su contenido es correcto, y que por lo tanto deben dejar de ser mostrados en esta lista de elementos inapropiados.
|
* Marcar como revisados cuando consideramos que esos elementos no deben ser moderados, que su contenido es correcto, y que por lo tanto deben dejar de ser mostrados en esta lista de elementos inapropiados.
|
||||||
|
|
||||||
Para facilitar la gestión, arriba encontramos un filtro con las secciones:
|
Para facilitar la gestión, arriba encontramos un filtro con las secciones:
|
||||||
Pendientes: las Propuestas/Debates/Comentarios sobre los que todavía no se ha pulsado "ocultar", "bloquear" o "marcar como revisados", y que por lo tanto deberían ser revisados todavía
|
|
||||||
Todos: mostrando todos las Propuestas/Debates/Comentarios de la web, y no sólo los marcados como inapropiados.
|
* Pendientes: las Propuestas/Debates/Comentarios sobre los que todavía no se ha pulsado "ocultar", "bloquear" o "marcar como revisados", y que por lo tanto deberían ser revisados todavía.
|
||||||
Marcados como revisados: los que algún moderador ha marcado como revisados y por lo tanto parecen correctos.
|
* Todos: mostrando todos las Propuestas/Debates/Comentarios de la web, y no sólo los marcados como inapropiados.
|
||||||
|
* Marcados como revisados: los que algún moderador ha marcado como revisados y por lo tanto parecen correctos.
|
||||||
|
|
||||||
Es recomendable revisar regularmente la sección "pendientes".
|
Es recomendable revisar regularmente la sección "pendientes".
|
||||||
|
|
||||||
@@ -136,12 +135,12 @@ Un buscador nos permite encontrar cualquier usuario introduciendo su nombre de u
|
|||||||
|
|
||||||
Desde aquí puedes gestionar usuarios a través de las siguientes acciones:
|
Desde aquí puedes gestionar usuarios a través de las siguientes acciones:
|
||||||
|
|
||||||
* Usuarios
|
* Usuarios.
|
||||||
* Editar cuenta de usuario
|
* Editar cuenta de usuario.
|
||||||
* Crear propuesta
|
* Crear propuesta.
|
||||||
* Apoyar propuestas
|
* Apoyar propuestas.
|
||||||
* Crear propuesta de inversión
|
* Crear propuesta de inversión.
|
||||||
* Apoyar propts. de inversión
|
* Apoyar propts. de inversión.
|
||||||
* Imprimir propuestas
|
* Imprimir propuestas.
|
||||||
* Imprimir propts. de inversión
|
* Imprimir propts. de inversión.
|
||||||
* Invitaciones para usuarios
|
* Invitaciones para usuarios.
|
||||||
|
|||||||
9
doc/en/dev_test_setup.md
Normal file
9
doc/en/dev_test_setup.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Configuration for development and test environments (Mac OS X)
|
||||||
|
|
||||||
|
## Linux
|
||||||
|
|
||||||
|
## Mac OS X
|
||||||
|
|
||||||
|
See [here](dev_test_setup_osx.md)
|
||||||
|
|
||||||
|
## Windows
|
||||||
128
doc/en/dev_test_setup_osx.md
Normal file
128
doc/en/dev_test_setup_osx.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Configuration for development and test environments (Mac OS X)
|
||||||
|
|
||||||
|
## Homebrew
|
||||||
|
|
||||||
|
Homebrew is a very popular package manager for OS X. It's advised to use it since it makes the installation of some of the dependencies much easier.
|
||||||
|
|
||||||
|
You can find the installation instructions at: [brew.sh](http://brew.sh)
|
||||||
|
|
||||||
|
## XCode and XCode Command Line Tools
|
||||||
|
|
||||||
|
To install *git* you'll first need to install *Xcode* (download it from the Mac App Store) and its *Xcode Command Line Tools* (you can install them from the Xcode's app menu)
|
||||||
|
|
||||||
|
## Git
|
||||||
|
|
||||||
|
You can download git from: [git-scm.com/download/mac](https://git-scm.com/download/mac)
|
||||||
|
|
||||||
|
## Ruby y rbenv
|
||||||
|
|
||||||
|
OS X already comes with a preinstalled Ruby version, but it's quite old and we need a newer one (2.2.3). One of the multiple ways of installing Ruby in OS X is through *rbenv*. The installation instructions are in its GitHub repository and are pretty straight-forward:
|
||||||
|
|
||||||
|
[github.com/rbenv/rbenv](https://github.com/rbenv/rbenv)
|
||||||
|
|
||||||
|
## Bundler
|
||||||
|
|
||||||
|
```
|
||||||
|
gem install bundler
|
||||||
|
```
|
||||||
|
|
||||||
|
## PostgreSQL (>=9.4)
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Once installed, we need to *initialize* it:
|
||||||
|
|
||||||
|
```
|
||||||
|
initdb /usr/local/var/postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we're going to configure some things related to the *default user*. First we start postgres server with:
|
||||||
|
|
||||||
|
```
|
||||||
|
postgres -D /usr/local/var/postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
At this point we're supposed to have postgres correctly installed and a default user will automatically be created (whose name will match our username). This user hasn't got a password yet.
|
||||||
|
|
||||||
|
If we run `psql` we'll login into the postgres console with the default user. Probably it will fail since its required that a default database exists for that user. We can create it by typing:
|
||||||
|
|
||||||
|
```
|
||||||
|
createdb 'your_username'
|
||||||
|
```
|
||||||
|
|
||||||
|
If we run `psql` again we should now get access to postgres console. With `\du` you can see the current users list.
|
||||||
|
|
||||||
|
In case you want to set a password for your user you can make it throught postgres console by:
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER USER your_username WITH PASSWORD 'your_password';
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we'll create the *consul* user, the one the application is using. Run in postgres console:
|
||||||
|
|
||||||
|
```
|
||||||
|
CREATE ROLE consul WITH PASSWORD '000';
|
||||||
|
ALTER ROLE consul WITH SUPERUSER;
|
||||||
|
ALTER ROLE consul WITH login;
|
||||||
|
```
|
||||||
|
|
||||||
|
If at any point during PostgreSQL installation you feel you have messed things up, you can uninstall it and start again by running:
|
||||||
|
|
||||||
|
```
|
||||||
|
brew uninstall postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll have to delete also this directory (otherwise the new installation will generate conflicts, source: [gist.github.com/lxneng/741932](https://gist.github.com/lxneng/741932)):
|
||||||
|
|
||||||
|
```
|
||||||
|
rm -rf /usr/local/var/postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
## Postgis
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install postgis
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ghostscript
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install ghostscript
|
||||||
|
```
|
||||||
|
|
||||||
|
## PhantomJS
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install phantomjs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cloning the repository
|
||||||
|
|
||||||
|
Now that we have all the dependencies installed we can download the repository:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/consul/consul.git
|
||||||
|
cd consul
|
||||||
|
bundle install
|
||||||
|
cp config/database.yml.example config/database.yml
|
||||||
|
cp config/secrets.yml.example config/secrets.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Now copy in `database.yml` the database user and password you used for *consul*.
|
||||||
|
|
||||||
|
After this:
|
||||||
|
|
||||||
|
```
|
||||||
|
rake db:create
|
||||||
|
rake db:setup
|
||||||
|
rake db:dev_seed
|
||||||
|
RAILS_ENV=test bin/rake db:setup
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
bundle exec rspec
|
||||||
|
```
|
||||||
9
doc/es/dev_test_setup.md
Normal file
9
doc/es/dev_test_setup.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# Configuración para los entornos de desarrollo y pruebas
|
||||||
|
|
||||||
|
## Linux
|
||||||
|
|
||||||
|
## Mac OS X
|
||||||
|
|
||||||
|
Consultar [aquí](dev_test_setup_osx.md)
|
||||||
|
|
||||||
|
## Windows
|
||||||
128
doc/es/dev_test_setup_osx.md
Normal file
128
doc/es/dev_test_setup_osx.md
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
# Configuración para los entornos de desarrollo y pruebas (Mac OS X)
|
||||||
|
|
||||||
|
## Homebrew
|
||||||
|
|
||||||
|
Homebrew es un gestor de paquetes para OS X muy popular. Es recomendable usarlo pues facilita enormemente la instalación de algunos de los paquetes necesarios.
|
||||||
|
|
||||||
|
Puedes encontrar las instrucciones de instalación en: [brew.sh](http://brew.sh)
|
||||||
|
|
||||||
|
## XCode y XCode Command Line Tools
|
||||||
|
|
||||||
|
Para utilizar git necesitarás instalar *Xcode* (está en la Mac App Store) y las *Xcode Command Line Tools* (se instalan desde el menú de Xcode).
|
||||||
|
|
||||||
|
## Git y Github
|
||||||
|
|
||||||
|
Puedes descargar git desde: [git-scm.com/download/mac](https://git-scm.com/download/mac)
|
||||||
|
|
||||||
|
## Ruby y rbenv
|
||||||
|
|
||||||
|
OS X ya viene con una versión preinstalada de ruby, pero es bastante vieja y en nuestro caso no nos sirve. Una de las formas de instalar Ruby es a través de rbenv. Las instrucciones de instalación están en su GitHub y son bastante claras:
|
||||||
|
|
||||||
|
[github.com/rbenv/rbenv](https://github.com/rbenv/rbenv)
|
||||||
|
|
||||||
|
Después instala la versión de Ruby 2.2.3
|
||||||
|
|
||||||
|
## Bundler
|
||||||
|
|
||||||
|
```
|
||||||
|
gem install bundler
|
||||||
|
```
|
||||||
|
|
||||||
|
## PostgreSQL (>=9.4)
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Una vez instalado es necesario *inicializar* la instalación:
|
||||||
|
|
||||||
|
```
|
||||||
|
initdb /usr/local/var/postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Ahora vamos a configurar algunos aspectos del usuario por defecto. Primero iniciamos el servidor de postgres con:
|
||||||
|
|
||||||
|
```
|
||||||
|
postgres -D /usr/local/var/postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
Llegados a este punto se supone que tenemos postgres correctamente instalado y se nos habrá creado un usuario por defecto (cuyo nombre es nuestro nombre de usuario), y que (todavía) no tiene contraseña.
|
||||||
|
|
||||||
|
Si ejecutamos `psql` accederemos a la consola de postgres con el usuario por defecto. Probablemente fallará porque es necesario que de antemano exista una base de datos por defecto para dicho usuario. Podemos crearla ejecutando sobre la terminal:
|
||||||
|
|
||||||
|
```
|
||||||
|
createdb 'tu_nombre_de_usuario'
|
||||||
|
```
|
||||||
|
|
||||||
|
Si ahora ejecutamos `psql` de nuevo deberíamos poder acceder correctamente a la consola de postgres. Si sobre la consola de postgres ejecutas `\du` puede ver la lista de usuarios actual.
|
||||||
|
|
||||||
|
En el caso de que quieras asignarte una contraseña puedes hacerlo desde la consola de postgres con:
|
||||||
|
|
||||||
|
```
|
||||||
|
ALTER USER tu_nombre_usuario WITH PASSWORD 'tu_contraseña';
|
||||||
|
```
|
||||||
|
|
||||||
|
Ahora vamos a crear el usuario *consul*, que es el que utiliza la aplicación. Ejecuta sobre la consola de postgres:
|
||||||
|
|
||||||
|
```
|
||||||
|
CREATE ROLE consul WITH PASSWORD '000';
|
||||||
|
ALTER ROLE consul WITH SUPERUSER;
|
||||||
|
ALTER ROLE consul WITH login;
|
||||||
|
```
|
||||||
|
|
||||||
|
Si en algún momento durante la instalación de PostgreSQL y postgis sospechas que te has equivocado y deseas desinstalarlo y volver a empezar desde cero:
|
||||||
|
|
||||||
|
```
|
||||||
|
brew uninstall postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
También tendrás que borrar el siguiente directorio para que no de conflictos cuando intentes volver a instalarlo (fuente: [gist.github.com/lxneng/741932](https://gist.github.com/lxneng/741932)):
|
||||||
|
|
||||||
|
```
|
||||||
|
rm -rf /usr/local/var/postgres
|
||||||
|
```
|
||||||
|
|
||||||
|
## Postgis
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install postgis
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ghostscript
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install ghostscript
|
||||||
|
```
|
||||||
|
|
||||||
|
## PhantomJS
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install phantomjs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Clonar el repositorio
|
||||||
|
|
||||||
|
Ahora que ya tenemos todas las dependencias instalado podemos bajarnos el proyecto:
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/consul/consul.git
|
||||||
|
cd consul
|
||||||
|
bundle install
|
||||||
|
cp config/database.yml.example config/database.yml
|
||||||
|
cp config/secrets.yml.example config/secrets.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Ahora copia en `database.yml` el usuario y la contraseña que pusiste para *consul*. Cuando ya lo hayas hecho:
|
||||||
|
|
||||||
|
```
|
||||||
|
rake db:create
|
||||||
|
rake db:setup
|
||||||
|
rake db:dev_seed
|
||||||
|
RAILS_ENV=test bin/rake db:setup
|
||||||
|
```
|
||||||
|
|
||||||
|
Para ejecutar los tests:
|
||||||
|
|
||||||
|
```
|
||||||
|
bundle exec rspec
|
||||||
|
```
|
||||||
@@ -163,6 +163,10 @@ FactoryGirl.define do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :archived do
|
||||||
|
created_at 25.months.ago
|
||||||
|
end
|
||||||
|
|
||||||
trait :with_hot_score do
|
trait :with_hot_score do
|
||||||
before(:save) { |d| d.calculate_hot_score }
|
before(:save) { |d| d.calculate_hot_score }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ feature 'Official positions' do
|
|||||||
@proposal1 = create(:proposal, author: @user1)
|
@proposal1 = create(:proposal, author: @user1)
|
||||||
@proposal2 = create(:proposal, author: @user2)
|
@proposal2 = create(:proposal, author: @user2)
|
||||||
|
|
||||||
featured_proposals = 3.times { create(:proposal) }
|
create_featured_proposals
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario "Index" do
|
scenario "Index" do
|
||||||
|
|||||||
@@ -3,48 +3,50 @@ require 'rails_helper'
|
|||||||
|
|
||||||
feature 'Proposals' do
|
feature 'Proposals' do
|
||||||
|
|
||||||
scenario 'Index' do
|
context 'Index' do
|
||||||
featured_proposals = create_featured_proposals
|
scenario 'Lists featured and regular proposals' do
|
||||||
proposals = [create(:proposal), create(:proposal), create(:proposal)]
|
featured_proposals = create_featured_proposals
|
||||||
|
proposals = [create(:proposal), create(:proposal), create(:proposal)]
|
||||||
|
|
||||||
visit proposals_path
|
visit proposals_path
|
||||||
|
|
||||||
expect(page).to have_selector('#proposals .proposal-featured', count: 3)
|
expect(page).to have_selector('#proposals .proposal-featured', count: 3)
|
||||||
featured_proposals.each do |featured_proposal|
|
featured_proposals.each do |featured_proposal|
|
||||||
within('#featured-proposals') do
|
within('#featured-proposals') do
|
||||||
expect(page).to have_content featured_proposal.title
|
expect(page).to have_content featured_proposal.title
|
||||||
expect(page).to have_css("a[href='#{proposal_path(featured_proposal)}']")
|
expect(page).to have_css("a[href='#{proposal_path(featured_proposal)}']")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
expect(page).to have_selector('#proposals .proposal', count: 3)
|
||||||
|
proposals.each do |proposal|
|
||||||
|
within('#proposals') do
|
||||||
|
expect(page).to have_content proposal.title
|
||||||
|
expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.title)
|
||||||
|
expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.summary)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_selector('#proposals .proposal', count: 3)
|
scenario 'Pagination' do
|
||||||
proposals.each do |proposal|
|
per_page = Kaminari.config.default_per_page
|
||||||
within('#proposals') do
|
(per_page + 5).times { create(:proposal) }
|
||||||
expect(page).to have_content proposal.title
|
|
||||||
expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.title)
|
visit proposals_path
|
||||||
expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.summary)
|
|
||||||
|
expect(page).to have_selector('#proposals .proposal', count: per_page)
|
||||||
|
|
||||||
|
within("ul.pagination") do
|
||||||
|
expect(page).to have_content("1")
|
||||||
|
expect(page).to have_content("2")
|
||||||
|
expect(page).to_not have_content("3")
|
||||||
|
click_link "Next", exact: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
expect(page).to have_selector('#proposals .proposal', count: 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'Paginated Index' do
|
|
||||||
per_page = Kaminari.config.default_per_page
|
|
||||||
(per_page + 5).times { create(:proposal) }
|
|
||||||
|
|
||||||
visit proposals_path
|
|
||||||
|
|
||||||
expect(page).to have_selector('#proposals .proposal', count: per_page)
|
|
||||||
|
|
||||||
within("ul.pagination") do
|
|
||||||
expect(page).to have_content("1")
|
|
||||||
expect(page).to have_content("2")
|
|
||||||
expect(page).to_not have_content("3")
|
|
||||||
click_link "Next", exact: false
|
|
||||||
end
|
|
||||||
|
|
||||||
expect(page).to have_selector('#proposals .proposal', count: 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
scenario 'Show' do
|
scenario 'Show' do
|
||||||
proposal = create(:proposal)
|
proposal = create(:proposal)
|
||||||
|
|
||||||
@@ -676,6 +678,95 @@ feature 'Proposals' do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature 'Archived proposals' do
|
||||||
|
|
||||||
|
scenario 'show on archived tab' do
|
||||||
|
create_featured_proposals
|
||||||
|
archived_proposals = create_archived_proposals
|
||||||
|
|
||||||
|
visit proposals_path
|
||||||
|
click_link 'Archived'
|
||||||
|
|
||||||
|
within("#proposals-list") do
|
||||||
|
archived_proposals.each do |proposal|
|
||||||
|
expect(page).to have_content(proposal.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'do not show in other index tabs' do
|
||||||
|
create_featured_proposals
|
||||||
|
archived_proposal = create(:proposal, :archived)
|
||||||
|
|
||||||
|
visit proposals_path
|
||||||
|
|
||||||
|
within("#proposals-list") do
|
||||||
|
expect(page).to_not have_content archived_proposal.title
|
||||||
|
end
|
||||||
|
|
||||||
|
orders = %w{hot_score confidence_score created_at relevance}
|
||||||
|
orders.each do |order|
|
||||||
|
visit proposals_path(order: order)
|
||||||
|
|
||||||
|
within("#proposals-list") do
|
||||||
|
expect(page).to_not have_content archived_proposal.title
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'do not show support buttons in index' do
|
||||||
|
create_featured_proposals
|
||||||
|
archived_proposals = create_archived_proposals
|
||||||
|
|
||||||
|
visit proposals_path(order: 'archival_date')
|
||||||
|
|
||||||
|
within("#proposals-list") do
|
||||||
|
archived_proposals.each do |proposal|
|
||||||
|
within("#proposal_#{proposal.id}_votes") do
|
||||||
|
expect(page).to_not have_css(".supports")
|
||||||
|
expect(page).to have_content "This proposal has been archived and can't collect supports"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'do not show support buttons in show' do
|
||||||
|
archived_proposal = create(:proposal, :archived)
|
||||||
|
|
||||||
|
visit proposal_path(archived_proposal)
|
||||||
|
expect(page).to_not have_css(".supports")
|
||||||
|
expect(page).to have_content "This proposal has been archived and can't collect supports"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'do not show in featured proposals section' do
|
||||||
|
featured_proposal = create(:proposal, :with_confidence_score, cached_votes_up: 100)
|
||||||
|
archived_proposal = create(:proposal, :archived, :with_confidence_score, cached_votes_up: 10000)
|
||||||
|
|
||||||
|
visit proposals_path
|
||||||
|
|
||||||
|
within("#featured-proposals") do
|
||||||
|
expect(page).to have_content(featured_proposal.title)
|
||||||
|
expect(page).to_not have_content(archived_proposal.title)
|
||||||
|
end
|
||||||
|
within("#proposals-list") do
|
||||||
|
expect(page).to_not have_content(featured_proposal.title)
|
||||||
|
expect(page).to_not have_content(archived_proposal.title)
|
||||||
|
end
|
||||||
|
|
||||||
|
click_link "Archived"
|
||||||
|
|
||||||
|
within("#featured-proposals") do
|
||||||
|
expect(page).to have_content(featured_proposal.title)
|
||||||
|
expect(page).to_not have_content(archived_proposal.title)
|
||||||
|
end
|
||||||
|
within("#proposals-list") do
|
||||||
|
expect(page).to_not have_content(featured_proposal.title)
|
||||||
|
expect(page).to have_content(archived_proposal.title)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
context "Search" do
|
context "Search" do
|
||||||
|
|
||||||
context "Basic search" do
|
context "Basic search" do
|
||||||
|
|||||||
@@ -204,6 +204,13 @@ describe Proposal do
|
|||||||
expect {proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(0)
|
expect {proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should not register vote for archived proposals" do
|
||||||
|
user = create(:user, verified_at: Time.now)
|
||||||
|
archived_proposal = create(:proposal, :archived)
|
||||||
|
|
||||||
|
expect {archived_proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(0)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#cached_votes_up' do
|
describe '#cached_votes_up' do
|
||||||
@@ -811,4 +818,30 @@ describe Proposal do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "archived" do
|
||||||
|
before(:each) do
|
||||||
|
@new_proposal = create(:proposal)
|
||||||
|
@archived_proposal = create(:proposal, :archived)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "archived? is true only for proposals created more than n (configured months) ago" do
|
||||||
|
expect(@new_proposal.archived?).to eq false
|
||||||
|
expect(@archived_proposal.archived?).to eq true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "scope archived" do
|
||||||
|
archived = Proposal.archived
|
||||||
|
|
||||||
|
expect(archived.size).to eq(1)
|
||||||
|
expect(archived.first).to eq(@archived_proposal)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "scope archived" do
|
||||||
|
not_archived = Proposal.not_archived
|
||||||
|
|
||||||
|
expect(not_archived.size).to eq(1)
|
||||||
|
expect(not_archived.first).to eq(@new_proposal)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -197,6 +197,11 @@ module CommonActions
|
|||||||
create(:proposal, title: "Fire and blood", question: "You talking to me?", cached_votes_up: Proposal.votes_needed_for_success + 1)]
|
create(:proposal, title: "Fire and blood", question: "You talking to me?", cached_votes_up: Proposal.votes_needed_for_success + 1)]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_archived_proposals
|
||||||
|
[create(:proposal, title: "This is an expired proposal", created_at: Setting["months_to_archive_proposals"].to_i.months.ago),
|
||||||
|
create(:proposal, title: "This is an oldest expired proposal", created_at: (Setting["months_to_archive_proposals"].to_i + 2).months.ago)]
|
||||||
|
end
|
||||||
|
|
||||||
def tag_names(tag_cloud)
|
def tag_names(tag_cloud)
|
||||||
tag_cloud.tags.map(&:name)
|
tag_cloud.tags.map(&:name)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user