Merge branch 'legislation-module-stable' into sandbox-html

This commit is contained in:
Amaia Castro
2016-12-27 12:36:10 +01:00
80 changed files with 1933 additions and 144 deletions

View File

@@ -67,6 +67,8 @@ gem 'redcarpet'
gem 'rails-assets-markdown-it', source: 'https://rails-assets.org'
gem 'cocoon'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'

View File

@@ -104,6 +104,7 @@ GEM
cliver (0.3.2)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
cocoon (1.2.9)
coffee-rails (4.2.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.2.x)
@@ -467,6 +468,7 @@ DEPENDENCIES
capistrano3-delayed-job (~> 1.0)
capybara
ckeditor (~> 4.2.0)
cocoon
coffee-rails (~> 4.2.1)
coveralls
daemons

View File

@@ -48,6 +48,7 @@
//= require social_share
//= require markdown-it
//= require markdown_editor
//= require cocoon
//= require allegations
//= require custom

View File

@@ -34,3 +34,4 @@
@include foundation-thumbnail;
@include foundation-title-bar;
@include foundation-top-bar;
@include foundation-menu-icon;

View File

@@ -246,7 +246,7 @@ a {
}
}
h2 {
h2, h3 {
font-size: $base-font-size;
}
}

View File

@@ -2,7 +2,6 @@ class Admin::BannersController < Admin::BaseController
has_filters %w{all with_active with_inactive}, only: :index
before_action :find_banner, only: [:edit, :update, :destroy]
before_action :banner_styles, only: [:edit, :new, :create, :update]
before_action :banner_imgs, only: [:edit, :new, :create, :update]
@@ -24,7 +23,6 @@ class Admin::BannersController < Admin::BaseController
end
def update
@banner.assign_attributes(banner_params)
if @banner.update(banner_params)
redirect_to admin_banners_path
else
@@ -43,10 +41,6 @@ class Admin::BannersController < Admin::BaseController
params.require(:banner).permit(:title, :description, :target_url, :style, :image, :post_started_at, :post_ended_at)
end
def find_banner
@banner = Banner.find(params[:id])
end
def banner_styles
@banner_styles = Setting.all.banner_style.map { |banner_style| [banner_style.value, banner_style.key.split('.')[1]] }
end

View File

@@ -31,7 +31,6 @@ class Admin::Legislation::DraftVersionsController < Admin::Legislation::BaseCont
def draft_version_params
params.require(:legislation_draft_version).permit(
:legislation_process_id,
:title,
:changelog,
:status,

View File

@@ -0,0 +1,39 @@
class Admin::Legislation::QuestionsController < Admin::Legislation::BaseController
load_and_authorize_resource :process, class: "Legislation::Process"
load_and_authorize_resource :question, class: "Legislation::Question", through: :process
def index
@questions = @process.questions
end
def create
@question.author = current_user
if @question.save
redirect_to admin_legislation_process_questions_path
else
render :new
end
end
def update
if @question.update(question_params)
redirect_to admin_legislation_process_questions_path
else
render :edit
end
end
def destroy
@question.destroy
redirect_to admin_legislation_process_questions_path
end
private
def question_params
params.require(:legislation_question).permit(
:title,
question_options_attributes: [:id, :value, :_destroy]
)
end
end

View File

@@ -1,9 +1,32 @@
class Legislation::ProcessesController < Legislation::BaseController
has_filters %w{open next past}, only: :index
load_and_authorize_resource
def index
@current_filter ||= 'open'
@processes = ::Legislation::Process.send(@current_filter).page(params[:page])
end
def show
end
def draft_publication
phase :draft_publication
end
def allegations
phase :allegations
end
def final_version_publication
phase :final_version_publication
end
private
def phase(phase)
@process = ::Legislation::Process.find(params[:process_id])
@phase = phase
render :phase
end
end

View File

@@ -0,0 +1,12 @@
class Legislation::QuestionsController < Legislation::BaseController
load_and_authorize_resource :process
load_and_authorize_resource :question, through: :process
has_orders %w{most_voted newest oldest}, only: :show
def show
@commentable = @question
@comment_tree = CommentTree.new(@commentable, params[:page], @current_order)
set_comment_flags(@comment_tree.comments)
end
end

View File

@@ -0,0 +1,12 @@
module LayoutsHelper
def layout_menu_link_to(text, path, is_active, options)
if is_active
content_tag(:span, t('shared.you_are_in'), class: 'sr-only') + ' ' +
link_to(text, path, options.merge(class: "active"))
else
link_to(text, path, options)
end
end
end

View File

@@ -0,0 +1,9 @@
module LegislationHelper
def format_date(date)
l(date, format: "%d %b %Y") if date
end
def legislation_question_path(question)
legislation_process_question_path(question.process, question)
end
end

View File

@@ -33,7 +33,7 @@ module Abilities
can :mark_featured, Debate
can :unmark_featured, Debate
can :comment_as_administrator, [Debate, Comment, Proposal]
can :comment_as_administrator, [Debate, Comment, Proposal, Legislation::Question]
can [:search, :create, :index, :destroy], ::Moderator
can [:search, :create, :index, :summary], ::Valuator
@@ -48,6 +48,8 @@ module Abilities
can [:manage], ::Legislation::Process
can [:manage], ::Legislation::DraftVersion
can [:manage], ::Legislation::Question
cannot :comment_as_moderator, ::Legislation::Question
end
end
end

View File

@@ -11,8 +11,9 @@ module Abilities
can :read, User
can [:search, :read], Annotation
can :new, DirectMessage
can [:read], Legislation::Process
can [:read, :draft_publication, :allegations, :final_version_publication], Legislation::Process
can [:read], Legislation::DraftVersion
can [:read], Legislation::Question
end
end
end

View File

@@ -5,7 +5,7 @@ module Abilities
def initialize(user)
self.merge Abilities::Moderation.new(user)
can :comment_as_moderator, [Debate, Comment, Proposal]
can :comment_as_moderator, [Debate, Comment, Proposal, Legislation::Question]
end
end
end

View File

@@ -10,7 +10,7 @@ class Comment < ActiveRecord::Base
validates :body, presence: true
validates :user, presence: true
validates_inclusion_of :commentable_type, in: ["Debate", "Proposal"]
validates_inclusion_of :commentable_type, in: ["Debate", "Proposal", "Legislation::Question"]
validate :validate_body_length

View File

@@ -3,6 +3,8 @@ class Legislation::Process < ActiveRecord::Base
include ActsAsParanoidAliases
has_many :draft_versions, class_name: 'Legislation::DraftVersion', foreign_key: 'legislation_process_id'
has_one :final_draft_version, -> { where final_version: true }, class_name: 'Legislation::DraftVersion', foreign_key: 'legislation_process_id'
has_many :questions, class_name: 'Legislation::Question', foreign_key: 'legislation_process_id'
validates :title, presence: true
validates :description, presence: true
@@ -17,7 +19,38 @@ class Legislation::Process < ActiveRecord::Base
validates :allegations_end_date, presence: true
validates :final_publication_date, presence: true
scope :open, -> {where("start_date <= ? and end_date >= ?", Time.current, Time.current) }
scope :next, -> {where("start_date > ?", Time.current) }
scope :past, -> {where("end_date < ?", Time.current) }
scope :open, -> {where("start_date <= ? and end_date >= ?", Date.current, Date.current) }
scope :next, -> {where("start_date > ?", Date.current) }
scope :past, -> {where("end_date < ?", Date.current) }
def open_phase?(phase)
today = Date.current
case phase
when :debate
today >= debate_start_date && today <= debate_end_date
when :draft_publication
today >= draft_publication_date
when :allegations
today >= allegations_start_date && today <= allegations_end_date
when :final_version_publication
today >= final_publication_date
end
end
def show_phase?(phase)
# show past phases even if they're finished
today = Date.current
case phase
when :debate
today >= debate_start_date
when :draft_publication
today >= draft_publication_date
when :allegations
today >= allegations_start_date
when :final_version_publication
today >= final_publication_date
end
end
end

View File

@@ -0,0 +1,19 @@
class Legislation::Question < ActiveRecord::Base
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
belongs_to :process, class_name: 'Legislation::Process', foreign_key: 'legislation_process_id'
has_many :question_options, class_name: 'Legislation::QuestionOption', foreign_key: 'legislation_question_id', dependent: :destroy, inverse_of: :question
has_many :comments, as: :commentable
accepts_nested_attributes_for :question_options, :reject_if => proc { |attributes| attributes[:value].blank? }, allow_destroy: true
validates :process, presence: true
validates :title, presence: true
def next_question_id
@next_question_id ||= process.questions.where("id > ?", id).order('id ASC').limit(1).pluck(:id).first
end
end

View File

@@ -0,0 +1,9 @@
class Legislation::QuestionOption < ActiveRecord::Base
acts_as_paranoid column: :hidden_at
include ActsAsParanoidAliases
belongs_to :question, class_name: 'Legislation::Question', foreign_key: 'legislation_question_id', inverse_of: :question_options
validates :question, presence: true
validates :value, presence: true, uniqueness: { scope: :legislation_question_id }
end

View File

@@ -9,7 +9,7 @@
<strong>
<%= @draft_version.errors.count %>
<%= t("admin.legislation.draft_versions.errors.form.error", count: @process.errors.count) %>
<%= t("admin.legislation.draft_versions.errors.form.error", count: @draft_version.errors.count) %>
</strong>
</div>

View File

@@ -1,6 +1,6 @@
<div class="legislation-draft-versions-index row">
<div class="small-12 column">
<%= link_to admin_legislation_processes_path, class: "back" do %>
<%= link_to admin_legislation_process_path(@process), class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.legislation.draft_versions.edit.back") %>
<% end %>

View File

@@ -1,6 +1,6 @@
<div class="legislation-draft-versions-index row">
<div class="small-12 column">
<%= link_to admin_legislation_processes_path, class: "back" do %>
<%= link_to admin_legislation_process_path(@process), class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.legislation.draft_versions.new.back") %>
<% end %>
@@ -12,6 +12,5 @@
<h3><%= t("admin.legislation.draft_versions.new.title") %></h3>
<%= render 'form', url: admin_legislation_process_draft_versions_path(@process) %>
</div>
</div>

View File

@@ -1,6 +1,9 @@
<ul class="menu simple clear">
<li <%= "class=active" if active == 'info' %>>
<%= link_to t("admin.legislation.processes.subnav.info"), edit_admin_legislation_process_path(process) %>
</li>
<li <%= "class=active" if active == 'questions' %>>
<%= link_to t("admin.legislation.processes.subnav.questions"), admin_legislation_process_questions_path(process) %>
</li>
<li <%= "class=active" if active == 'draft_versions' %>>
<%= link_to t("admin.legislation.processes.subnav.draft_texts"), admin_legislation_process_draft_versions_path(process) %>

View File

@@ -0,0 +1,46 @@
<%= form_for [:admin, @process, @question], url: url do |f| %>
<% if @question.errors.any? %>
<div id="error_explanation" data-alert class="callout alert" data-closable>
<button class="close-button" aria-label="<%= t("application.close") %>" type="button" data-close>
<span aria-hidden="true">&times;</span>
</button>
<strong>
<%= @question.errors.count %>
<%= t("admin.legislation.questions.errors.form.error", count: @question.errors.count) %>
</strong>
</div>
<% end %>
<div class="row">
<div class="small-12 medium-4 column">
<%= f.label :title %>
</div>
<div class="small-12 medium-8 column">
<%= f.text_area :title, rows: 5, label: false %>
</div>
</div>
<div class="row">
<div class="small-12 medium-4 column">
<%= f.label :question_options %>
</div>
<div class="small-12 medium-8 column">
<%= f.fields_for :question_options do |ff| %>
<%= render 'question_option_fields', f: ff %>
<% end %>
</div>
<div class="small-12 medium-8 column">
<%= link_to_add_association t('.add_option'), f, :question_options %>
</div>
</div>
<div class="row">
<div class="actions small-12 medium-3 column">
<%= f.submit(class: "button expanded", value: t("admin.legislation.questions.#{admin_submit_action(@question)}.submit_button")) %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<div class="nested-fields">
<div class="field">
<%= f.text_field :value, label: false %>
<%= link_to_remove_association t('.remove_option'), f %>
</div>
</div>

View File

@@ -0,0 +1,20 @@
<div class="legislation-questions-index row">
<div class="small-12 column">
<%= link_to admin_legislation_process_path(@process), class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.legislation.questions.edit.back") %>
<% end %>
<h1><%= @process.title %></h1>
<%= render 'admin/legislation/processes/subnav', process: @process, active: 'questions' %>
<h3><%= @question.title %></h3>
<%= render 'form', url: admin_legislation_process_question_path(@process, @question) %>
<%= link_to t("admin.legislation.processes.index.delete"), admin_legislation_process_question_path(@process, @question),
method: :delete,
class: 'button hollow alert' %>
</div>
</div>

View File

@@ -0,0 +1,42 @@
<div class="legislation-draft-versions-index row">
<div class="small-12 column">
<%= link_to admin_legislation_processes_path, class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.legislation.questions.index.back") %>
<% end %>
<h1><%= @process.title %></h1>
<%= render 'admin/legislation/processes/subnav', process: @process, active: 'questions' %>
<%= link_to t("admin.legislation.questions.index.create"),
new_admin_legislation_process_question_path, class: "button float-right" %>
<h3><%= t("admin.legislation.questions.index.title") %></h3>
<table>
<tr>
<th><%= t("admin.legislation.questions.table.title") %></th>
<th><%= t("admin.legislation.questions.table.question_options") %></th>
<th><%= t("admin.legislation.questions.table.answers_count") %></th>
<th><%= t("admin.legislation.questions.table.comments_count") %></th>
</tr>
<% @process.questions.each do |question| %>
<tr id="<%= dom_id(question) %>">
<td>
<%= link_to question.title, edit_admin_legislation_process_question_path(@process, question) %>
</td>
<td>
<%= content_tag :ul do %>
<% question.question_options.each do |question_option| %>
<%= content_tag :li, question_option.value %>
<% end %>
<% end %>
</td>
<td><%= question.answers_count %></td>
<td><%= question.comments.count %></td>
</tr>
<% end %>
</table>
</div>
</div>

View File

@@ -0,0 +1,16 @@
<div class="legislation-questions-index row">
<div class="small-12 column">
<%= link_to admin_legislation_process_path(@process), class: "back" do %>
<span class="icon-angle-left"></span>
<%= t("admin.legislation.questions.new.back") %>
<% end %>
<h1><%= @process.title %></h1>
<%= render 'admin/legislation/processes/subnav', process: @process, active: 'questions' %>
<h3><%= t("admin.legislation.questions.new.title") %></h3>
<%= render 'form', url: admin_legislation_process_questions_path(@process) %>
</div>
</div>

View File

@@ -1,6 +1,6 @@
<% cache [locale_and_user_status(comment), comment, commentable_cache_key(comment.commentable), comment.author, (@comment_flags[comment.id] if @comment_flags)] do %>
<div class="row">
<div id="<%= dom_id(comment) %>" class="comment small-12 column">
<ul id="<%= dom_id(comment) %>" class="comment no-bullet small-12 column">
<% if comment.hidden? || comment.user.hidden? %>
<% if comment.children.size > 0 %>
@@ -23,7 +23,7 @@
<% end %>
<% end %>
<div class="comment-body">
<li class="comment-body">
<div class="comment-info">
<% if comment.as_administrator? %>
@@ -92,14 +92,13 @@
<%= render 'comments/form', {commentable: comment.commentable, parent_id: comment.id, toggeable: true} %>
<% end %>
</div>
</div>
</li>
<% end %>
<div id="<%= dom_id(comment) %>_children" class="comment-children">
<ul id="<%= dom_id(comment) %>_children" class="no-bullet comment-children">
<% child_comments_of(comment).each do |child| %>
<%= render 'comments/comment', comment: child %>
<% end %>
</div>
</div>
</ul>
</ul>
</div>
<% end %>

View File

@@ -1,31 +1,29 @@
<% cache [locale_and_user_status, @current_order, commentable_cache_key(@debate), @comment_tree.comments, @comment_tree.comment_authors, @debate.comments_count, @comment_flags] do %>
<section class="row-full comments">
<div class="row">
<div id="comments" class="small-12 column">
<h2>
<%= t("debates.show.comments_title") %>
<span class="js-comments-count">(<%= @debate.comments_count %>)</span>
</h2>
<div class="row comments">
<div id="comments" class="small-12 column">
<h3>
<%= t("debates.show.comments_title") %>
<span class="js-comments-count">(<%= @debate.comments_count %>)</span>
</h3>
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @debate, parent_id: nil, toggeable: false} %>
<% else %>
<br>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @debate, parent_id: nil, toggeable: false} %>
<% else %>
<br>
<div data-alert class="callout primary">
<%= t("debates.show.login_to_comment",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<div data-alert class="callout primary">
<%= t("debates.show.login_to_comment",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>
</section>
</div>
<% end %>

View File

@@ -1,6 +1,6 @@
<% provide :title do %><%= @debate.title %><% end %>
<% cache [locale_and_user_status(@debate), @debate, @debate.author, Flag.flagged?(current_user, @debate), @debate_votes] do %>
<section class="debate-show">
<div class="debate-show">
<div id="<%= dom_id(@debate) %>" class="row">
<div class="small-12 medium-9 column">
<%= render "shared/back_link" %>
@@ -59,7 +59,7 @@
<% end %>
</div>
</div>
</section>
</div>
<% end %>
<%= render "comments" %>

View File

@@ -16,12 +16,7 @@
<div class="top-bar-title">
<%= link_to root_path, class: "hide-for-small-only", accesskey: "/" do %>
<%= image_tag('logo_header.png', class: 'hide-for-small-only float-left', size: '80x80', alt: t("layouts.header.logo")) %>
<% if opendata_page? %>
<%= t("layouts.header.open_gov", open: "#{t('layouts.header.open')}") %> <span>|</span>
<span class="logo-site"><%= t("layouts.header.open_data") %></span>
<% else %>
<%= setting['org_name'] %>
<% end %>
<%= setting['org_name'] %>
<% end %>
</div>
@@ -34,9 +29,6 @@
<div class="show-for-small-only">
<div class="subnavigation row">
<%= render "shared/subnavigation" %>
<div class="small-12 medium-3 column">
<%= yield :header_addon %>
</div>
</div>
</div>
</div>
@@ -48,9 +40,9 @@
<div class="row">
<div class="hide-for-small-only">
<%= render "shared/subnavigation" %>
<div class="small-12 medium-3 column">
<%= yield :header_addon %>
</div>
</div>
<div class="small-12 medium-3 column">
<%= yield :header_addon %>
</div>
</div>
</div>

View File

@@ -14,7 +14,7 @@
<%= csrf_meta_tags %>
<%= favicon_link_tag "favicon.ico" %>
<%= favicon_link_tag "apple-touch-icon-200.png",
rel: "apple-touch-icon",
rel: "icon apple-touch-icon",
sizes: "200x200",
type: "image/png" %>
<%= content_for :social_media_meta_tags %>

View File

@@ -1,3 +1,5 @@
<% provide :title do %><%= "#{@draft_version.title} - #{t('.title')} - #{@process.title}" %><% end %>
<div class="row">
<h2><%= @process.title %></h2>
<h2><%= @draft_version.title %></h2>

View File

@@ -1,3 +1,5 @@
<% provide :title do %><%= "#{@draft_version.title} - #{@process.title}" %><% end %>
<div class="row">
<h2><%= link_to @process.title, @process %></h2>
<h2><%= @draft_version.title %></h2>

View File

@@ -0,0 +1,14 @@
<div class="small-12 medium-9 column">
<div class="debate-list">
<% if process.questions.empty? %>
<p><%= t('.empty_questions') %></p>
<% else %>
<%= render process.questions %>
<% end %>
</div>
</div>
<div class="small-12 medium-3 column">
<div class="debate-info"><%= t('.participate') %></div>
</div>

View File

@@ -0,0 +1,37 @@
<div class="legislation-hero no-margin-top grey-heading">
<div class="row headline">
<div class="small-12 medium-7 column">
<p class="grey"><%= t('.title') %></p>
<h2>
<%= process.title %>
</h2>
</div>
<div class="small-12 medium-4 column right">
<a class="button-subscribe expanded button strong" title="Suscríbete al proceso" data-remote="true" rel="nofollow" data-method="post" href="/proposals/6-soluta-sed-sapiente-dolores/vote?value=yes">
<h3>Suscríbete al proceso</h3>
<p>Recibe notificaciones clave sobre el proceso</p>
</a>
</div>
</div>
<div class="row description">
<div class="small-12 medium-4 column">
<h4><%= t('.description') %></h4>
<%= markdown process.description %>
</div>
<div class="small-12 medium-4 column">
<h4><%= t('.target') %></h4>
<%= markdown process.target %>
</div>
<div class="small-12 medium-4 column">
<h4><%= t('.how_to_participate') %></h4>
<%= markdown process.how_to_participate %>
</div>
</div>
<div class="center half-gradient">
<a class="button big center strong" title="<%= t('.more_info') %>">
<%= t('.more_info') %>
</a>
</div>
</div>

View File

@@ -0,0 +1,29 @@
<nav class="legislation-process-categories">
<%= render 'legislation/processes/key_dates_svg' %>
<ul>
<li <%= "class=active" if phase == :debate %>>
<%= link_to process do %>
<h4><%= t('legislation.processes.shared.debate_dates') %></h4>
<p><%= format_date(process.debate_start_date) %> - <%= format_date(process.debate_end_date) %></p>
<% end %>
</li>
<li <%= "class=active" if phase == :draft_publication %>>
<%= link_to legislation_process_draft_publication_path(process) do %>
<h4><%= t('legislation.processes.shared.draft_publication_date') %></h4>
<p><%= format_date(process.draft_publication_date) %></p>
<% end %>
</li>
<li <%= "class=active" if phase == :allegations %>>
<%= link_to legislation_process_allegations_path(process) do %>
<h4><%= t('legislation.processes.shared.allegations_dates') %></h4>
<p><%= format_date(process.allegations_start_date) %> - <%= format_date(process.allegations_end_date) %></p>
<% end %>
</li>
<li <%= "class=active" if phase == :final_version_publication %>>
<%= link_to legislation_process_final_version_publication_path(process) do %>
<h4><%= t('legislation.processes.shared.final_publication_date') %></h4>
<p><%= format_date(process.final_publication_date) %></p>
<% end %>
</li>
</ul>
</nav>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 59 KiB

View File

@@ -0,0 +1,9 @@
<% if process.draft_versions.any? %>
<ul>
<% process.draft_versions.each do |draft_version| %>
<li><%= link_to draft_version.title, legislation_process_draft_version_path(process, draft_version) %></li>
<% end %>
</ul>
<% else %>
<p><%= t('.empty') %></p>
<% end %>

View File

@@ -0,0 +1,9 @@
<% if process.draft_versions.any? %>
<ul>
<% process.draft_versions.each do |draft_version| %>
<li><%= link_to draft_version.title, legislation_process_draft_version_path(process, draft_version) %></li>
<% end %>
</ul>
<% else %>
<p><%= t('.empty') %></p>
<% end %>

View File

@@ -0,0 +1,5 @@
<% if process.final_draft_version %>
<p><%= legislation_process_draft_version_path(process.final_draft_version) %></p>
<% else %>
<p><%= t('.empty') %></p>
<% end %>

View File

@@ -0,0 +1,13 @@
<div class="debate-draft">
<div class="small-12 medium-7 column">
<h3><%= t('.not_open') %></h3>
<p>Suscríbete al proceso para recibir un aviso en el momento en que se abra.</p>
</div>
<div class="small-12 medium-5 column">
<button class="button-subscribe expanded button strong" title="Suscríbete al proceso" data-remote="true" rel="nofollow" data-method="post" href="/proposals/6-soluta-sed-sapiente-dolores/vote?value=yes">
<h3>Suscríbete al proceso</h3>
<p>Recibe notificaciones clave sobre el proceso</p>
</button>
</div>
</div>

View File

@@ -0,0 +1,41 @@
<div id="<%= dom_id(process) %>" class="legislation clear">
<div class="column row legislation-text">
<div class="small-12 medium-8 column">
<div class="legislation-text">
<h3><%= link_to process.title, process %></h3>
<p><%= process.description %></p>
</div>
</div>
<div class="small-12 medium-4 column">
<%= link_to process, class: "button button-legislation big expanded", title: t('.see_latest_comments_title') do %>
<span class="icon-comments"></span>&nbsp; <%= t('.see_latest_comments') %>
<% end %>
</div>
</div>
<div class="column row">
<div class="small-12 column legislation-calendar-info">
<p><%= t('legislation.processes.shared.key_dates') %></p>
</div>
</div>
<div class="column row small-collapse medium-uncollapse legislation-calendar">
<div class="small-6 medium-3 column">
<h5><%= t('legislation.processes.shared.debate_dates') %></h5>
<p><%= format_date(process.debate_start_date) %> - <%= format_date(process.debate_end_date) %></p>
</div>
<div class="small-6 medium-3 column">
<h5><%= t('legislation.processes.shared.draft_publication_date') %></h5>
<p><%= format_date(process.draft_publication_date) %></p>
</div>
<div class="small-6 medium-3 column">
<h5><%= t('legislation.processes.shared.allegations_dates') %></h5>
<p><%= format_date(process.allegations_start_date) %> - <%= format_date(process.allegations_end_date) %></p>
</div>
<div class="small-6 medium-3 column">
<h5><%= t('legislation.processes.shared.final_publication_date') %></h5>
<p><%= format_date(process.final_publication_date) %></p>
</div>
</div>
</div>

View File

@@ -1,5 +1,22 @@
<div class="row">
<% @processes.each do |process| %>
<%= link_to process.title, process %><br/>
<% end %>
<div class="legislation-hero no-margin-top brand-heading">
<div class="row">
<div class="small-12 medium-12 column padding">
<h4>
<%= t('.hightlighted_processes') %>
</h4>
</div>
</div>
</div>
<div class="row">
<div class="legislation-categories small-12 medium-3 column">
<%= render 'shared/filter_subnav', i18n_namespace: "legislation.processes.index" %>
</div>
<div id="legislation" class="legislation-list small-12 medium-9 column">
<div id="legislation-list">
<%= render @processes %>
<%= paginate @processes %>
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
<% provide :title do %><%= @process.title %><% end %>
<%= render 'legislation/processes/header_full', process: @process %>
<div class="row">
<%= render 'legislation/processes/key_dates', process: @process, phase: @phase %>
<div class="debate-chooser">
<div class="row">
<% if @process.show_phase?(@phase) %>
<%= render "phase_#{@phase}", process: @process %>
<% else %>
<%= render 'legislation/processes/phase_not_open' %>
<% end %>
</div>
</div>
</div>

View File

@@ -1,9 +1,17 @@
<% provide :title do %><%= @process.title %><% end %>
<%= render 'header_full', process: @process %>
<div class="row">
<%= render 'key_dates', process: @process, phase: :debate %>
<h1><%= @process.title %></h1>
<% @process.draft_versions.each do |draft_version| %>
<%= link_to draft_version.title, legislation_process_draft_version_path(@process, draft_version) %>
<% end %>
<div class="debate-chooser">
<div class="row">
<% if @process.show_phase?(:debate) %>
<%= render 'debate', process: @process %>
<% else %>
<%= render 'phase_not_open' %>
<% end %>
</div>
</div>
</div>

View File

@@ -0,0 +1,29 @@
<% cache [locale_and_user_status, @current_order, commentable_cache_key(@question), @comment_tree.comments, @comment_tree.comment_authors, @question.comments_count, @comment_flags] do %>
<div class="row comments">
<div id="comments" class="small-12 column">
<h3>
<%= t("legislation.questions.show.comments") %>
<span class="js-comments-count">(<%= @question.comments_count %>)</span>
</h3>
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @question, parent_id: nil, toggeable: false} %>
<% else %>
<br>
<div data-alert class="callout primary">
<%= t("debates.show.login_to_comment",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,11 @@
<div class="debate-block">
<div class="debate-type">
<%= t('.debate') %> <span class="icon-debates" aria-hidden="true"></span>
</div>
<div class="debate-title">
<h4><%= link_to question.title, legislation_process_question_path(question.process, question) %></h4>
</div>
<div class="debate-meta">
<span class="icon-comments" aria-hidden="true"></span> <span class="debate-comments"><%= link_to t('.comments', count: question.comments.count), legislation_process_question_path(question.process, question) %></span> · <span class="debate-date"><%= format_date question.created_at %></span>
</div>
</div>

View File

@@ -0,0 +1,52 @@
<% provide :title do %><%= @question.title %><% end %>
<section class="debate-quiz">
<div class="quiz-header row small-collapse">
<div class="small-12 medium-9 column">
<div class="quiz-title">
<p class="quiz-header-title"><%= t('.title') %></p>
<h4><%= link_to @process.title, @process %></h4>
</div>
</div>
<div class="small-12 medium-3 column">
<% if @question.next_question_id %>
<%= link_to legislation_process_question_path(@process, @question.next_question_id), class: "quiz-next-link" do %>
<%= content_tag :div, class: "quiz-next" do %>
<%= t('.next_question') %>
<span class="icon-angle-right" aria-hidden="true">
<% end %>
<% end %>
<% end %>
</div>
</div>
<div class="row">
<div class="small-12 medium-9 column">
<h3 class="quiz-question"><%= @question.title %></h3>
<div class="debate-questions">
<form class="controls-stacked">
<% @question.question_options.each do |question_option| %>
<label class="control radio">
<input id="quiz-1" name="radio" type="radio">
<span class="control-indicator"></span>
<%= question_option.value %>
</label>
<% end %>
</form>
</div>
</div>
<aside class="small-12 medium-3 column">
<div id="social-share" class="sidebar-divider"></div>
<h3><%= t('.share') %></h3>
<div class="social-share-full">
<div class="social-share-button" data-title="<%= @question.title %>" data-img="" data-url="" data-desc="" data-via="">
<a rel="nofollow " data-site="twitter" class="ssb-icon ssb-twitter" onclick="return SocialShareButton.share(this);" title="<%= t('.share_twitter') %>" href="#"><span class="sr-only">twitter</span></a>
<a rel="nofollow " data-site="facebook" class="ssb-icon ssb-facebook" onclick="return SocialShareButton.share(this);" title="<%= t('.share_facebook') %>" href="#"><span class="sr-only">facebook</span></a>
<a rel="nofollow " data-site="google_plus" class="ssb-icon ssb-google_plus" onclick="return SocialShareButton.share(this);" title="<%= t('.share_gplus') %>" href="#"><span class="sr-only">google_plus</span></a>
</div>
</div>
</div>
</div>
</section>
<%= render 'comments' %>

View File

@@ -1,26 +1,24 @@
<% cache [locale_and_user_status, @current_order, commentable_cache_key(@proposal), @comment_tree.comments, @comment_tree.comment_authors, @proposal.comments_count, @comment_flags] do %>
<section class="comments">
<div class="row">
<div id="comments" class="small-12 column">
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<div class="row comments">
<div id="comments" class="small-12 column">
<%= render 'shared/wide_order_selector', i18n_namespace: "comments" %>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @proposal, parent_id: nil, toggeable: false} %>
<% else %>
<br>
<% if user_signed_in? %>
<%= render 'comments/form', {commentable: @proposal, parent_id: nil, toggeable: false} %>
<% else %>
<br>
<div data-alert class="callout primary">
<%= t("proposals.show.login_to_comment",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<div data-alert class="callout primary">
<%= t("proposals.show.login_to_comment",
signin: link_to(t("votes.signin"), new_user_session_path),
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
</div>
<% end %>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>
<% @comment_tree.root_comments.each do |comment| %>
<%= render 'comments/comment', comment: comment %>
<% end %>
<%= paginate @comment_tree.root_comments %>
</div>
</section>
</div>
<% end %>

View File

@@ -3,18 +3,18 @@
<ul class="tabs" data-tabs id="example-tabs">
<li class="tabs-title is-active">
<%= link_to "#tab-comments" do %>
<h2>
<h3>
<%= t("proposals.show.comments_tab") %>
<span class="js-comments-count">(<%= @proposal.comments_count %>)</span>
</h2>
</h3>
<% end %>
</li>
<li class="tabs-title">
<%= link_to "#tab-notifications" do %>
<h2>
<h3>
<%= t("proposals.show.notifications_tab") %>
(<%= @notifications.count %>)
</h2>
</h3>
<% end %>
</li>
</ul>

View File

@@ -6,8 +6,7 @@
social_description: @proposal.summary %>
<% end %>
<% cache [locale_and_user_status(@proposal), @proposal, @proposal.author, Flag.flagged?(current_user, @proposal), @proposal_votes] do %>
<section class="proposal-show">
<div class="proposal-show">
<div id="<%= dom_id(@proposal) %>" class="row">
<div class="small-12 medium-9 column">
<%= render "shared/back_link" %>
@@ -134,7 +133,7 @@
</div>
</aside>
</div>
</section>
</div>
<% end %>
<div class="tabs-content" data-tabs-content="example-tabs">

View File

@@ -15,14 +15,14 @@
</div>
<div class="small-12 large-3 column">
<label><%= t("shared.advanced_search.author_type") %></label>
<label for="advanced_search_official_level"><%= t("shared.advanced_search.author_type") %></label>
<%= select_tag('advanced_search[official_level]', official_level_search_options,
include_blank: t("shared.advanced_search.author_type_blank")) %>
</div>
<div class="small-12 large-9">
<div class="small-12 large-4 column">
<label><%= t("shared.advanced_search.date") %></label>
<label for="js-advanced-search-date-min"><%= t("shared.advanced_search.date") %></label>
<%= select_tag('advanced_search[date_min]', date_range_options,
include_blank: t("shared.advanced_search.date_range_blank"),
id: 'js-advanced-search-date-min') %>
@@ -31,14 +31,18 @@
<div id='js-custom-date' class='small-12 large-8 column' style="display: none">
<div class="row">
<div class='small-12 large-6 column'>
<label><%= t("shared.advanced_search.from") %> (<%= t("shared.advanced_search.date_placeholder") %>)</label>
<label for="advanced_search_date_min">
<%= t("shared.advanced_search.from") %> (<%= t("shared.advanced_search.date_placeholder") %>)
</label>
<%= text_field_tag 'advanced_search[date_min]',
params[:advanced_search].try(:[], :date_min),
placeholder: t("shared.advanced_search.date_placeholder"),
class: 'js-calendar' %>
</div>
<div class='small-12 large-6 column'>
<label><%= t("shared.advanced_search.to") %> (<%= t("shared.advanced_search.date_placeholder") %>)</label>
<label for="advanced_search_date_max">
<%= t("shared.advanced_search.to") %> (<%= t("shared.advanced_search.date_placeholder") %>)
</label>
<%= text_field_tag 'advanced_search[date_max]',
params[:advanced_search].try(:[], :date_max),
placeholder: t("shared.advanced_search.date_placeholder"),

View File

@@ -1,9 +1,11 @@
<div class="submenu">
<ul class="no-bullet submenu">
<% valid_orders.each do |order| %>
<%= link_to current_path_with_query_params(order: order, page: 1), class: order == @current_order ? 'active' : '' do %>
<%= content_tag(order == @current_order ? :h2 : :span) do %>
<%= t("#{i18n_namespace}.orders.#{order}") %>
<li class="inline-block">
<%= link_to current_path_with_query_params(order: order, page: 1), class: order == @current_order ? 'active' : '' do %>
<%= content_tag(order == @current_order ? :h2 : :span) do %>
<%= t("#{i18n_namespace}.orders.#{order}") %>
<% end %>
<% end %>
<% end %>
</li>
<% end %>
</div>
</ul>

View File

@@ -2,14 +2,23 @@
<ul>
<% if feature?(:debates) %>
<li>
<%= link_to t("layouts.header.debates"), debates_path, class: ("active" if controller_name == "debates"), accesskey: "d" %>
<%= layout_menu_link_to t("layouts.header.debates"),
debates_path,
controller_name == 'debates',
accesskey: "d" %>
</li>
<% end %>
<li>
<%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if controller_name == "proposals"), accesskey: "p" %>
<%= layout_menu_link_to t("layouts.header.proposals"),
proposals_path,
controller_name == 'proposals',
accesskey: "p" %>
</li>
<li>
<%= link_to t("layouts.header.proposal_ballot"), proposal_ballots_path, class: ("active" if controller_name == "proposal_ballots"), accesskey: "v" %>
<%= layout_menu_link_to t("layouts.header.proposal_ballot"),
proposal_ballots_path,
controller_name == 'proposal_ballots',
accesskey: "v" %>
</li>
<% if feature?(:legislation) %>
<li>
@@ -18,11 +27,11 @@
<% end %>
<% if feature?(:spending_proposals) %>
<li>
<%= link_to t("layouts.header.spending_proposals"), spending_proposals_path, class: ("active" if controller_name == "spending_proposals"), accesskey: "s" %>
<%= layout_menu_link_to t("layouts.header.spending_proposals"),
spending_proposals_path,
controller_name == 'spending_proposals',
accesskey: "s" %>
</li>
<% end %>
<li>
<%= link_to t("layouts.header.more_information"), page_path('more_information'), class: ("active" if current_page?("/more_information")), accesskey: "i" %>
</li>
</ul>
</div>

View File

@@ -1,7 +1,7 @@
<%- limit ||= nil %>
<% if taggable.tags.any? %>
<ul id="tags" class="no-bullet tags">
<ul id="tags_<%= dom_id(taggable) %>" class="no-bullet tags">
<% taggable.tag_list_with_limit(limit).each do |tag| %>
<li class="inline-block"><%= link_to sanitize(tag.name), send("#{taggable.class.name.underscore.pluralize}_path", search: tag.name) %></li>
<% end %>

View File

@@ -2,8 +2,26 @@
<div class="row">
<%= render "shared/locale_switcher" %>
<ul class="no-bullet external-links">
<li class="inline-block"><%= link_to t("layouts.header.external_link_transparency"), t("layouts.header.external_link_transparency_url") %>&nbsp;|</li>
<li class="inline-block"><%= link_to t("layouts.header.external_link_opendata"), "/opendata", class: ("selected" if current_page?("/opendata")) %></li>
<li class="inline-block">
<%= link_to t("layouts.header.more_information"),
page_path('more_information'),
class: ("selected" if current_page?("/more_information")),
accesskey: "i" %>
&nbsp;|
</li>
<li class="inline-block">
<%= link_to t("layouts.header.external_link_transparency"),
t("layouts.header.external_link_transparency_url"),
target: "_blank",
title: t('shared.target_blank_html') %>
&nbsp;|
</li>
<li class="inline-block">
<%= link_to t("layouts.header.external_link_opendata"),
t("layouts.header.external_link_opendata_url"),
target: "_blank",
title: t('shared.target_blank_html') %>
</li>
<% if setting['blog_url'] %>
<li class="inline-block">|&nbsp;
<%= link_to setting['blog_url'], title: t('shared.target_blank_html'), target: "_blank" do %>

View File

@@ -120,6 +120,7 @@ ignore_unused:
- 'admin.legislation.processes.index.filter*'
- 'admin.legislation.processes.*.submit_button'
- 'admin.legislation.draft_versions.*.submit_button'
- 'admin.legislation.questions.*.submit_button'
- 'admin.comments.index.hidden_*'
- 'admin.settings.index.features.*'
- 'moderation.comments.index.filter*'
@@ -141,6 +142,7 @@ ignore_unused:
- 'notifications.index.comments_on*'
- 'notifications.index.replies_to*'
- 'notifications.index.proposal_notification*'
- 'legislation.processes.index.filter*'
- 'helpers.page_entries_info.*' # kaminari
- 'views.pagination.*' # kaminari
- 'shared.suggest.*'

View File

@@ -108,6 +108,7 @@ en:
subnav:
info: Information
draft_texts: Text
questions: Debate
draft_versions:
edit:
back: Back
@@ -128,11 +129,35 @@ en:
draft: Draft
published: Published
table:
title: Títle
title: Title
created_at: Created at
comments: Comments
final_version: Final version
status: Status
questions:
edit:
back: Back
submit_button: Save changes
errors:
form:
error: Error
form:
add_option: Add option
index:
back: Back
title: Questions
create: Create question
new:
back: Back
title: Create new question
submit_button: Create question
table:
title: Title
question_options: Question options
answers_count: Answers count
comments_count: Comments count
question_option_fields:
remove_option: Remove option
managers:
index:
title: Managers

View File

@@ -106,6 +106,7 @@ es:
subnav:
info: Información
draft_texts: Texto
questions: Debate
draft_versions:
edit:
back: Volver
@@ -131,6 +132,30 @@ es:
comments: Comentarios
final_version: Versión final
status: Estado
questions:
edit:
back: Volver
submit_button: Guardar cambios
errors:
form:
error: Error
form:
add_option: +Añadir respuesta cerrada
index:
back: Volver
title: Preguntas
create: Crear pregunta
new:
back: Volver
title: Crear nueva pregunta
submit_button: Crear pregunta
table:
title: Título
question_options: Opciones de respuesta
answers_count: Número de respuestas
comments_count: Número de comentarios
question_option_fields:
remove_option: Eliminar
managers:
index:
title: Gestores

View File

@@ -190,6 +190,7 @@ en:
debates: Debates
external_link_blog: Blog
external_link_opendata: Open data
external_link_opendata_url: "/opendata"
external_link_transparency: Transparency
external_link_transparency_url: https://transparency.consul
locale: 'Language:'
@@ -208,7 +209,6 @@ en:
open: open
open_city_slogan_html: There are cities that are governed directly by their inhabitants, who <b>discuss</b> the topics they are concerned about, <b>propose</b> ideas to improve their lives and <b>decide</b> among themselves which ones will be carried out.
open_city_title: Love the city, and it will become a city you love.
open_data: Open data
open_gov: Open government
proposals: Proposals
proposal_ballot: Voting
@@ -224,9 +224,58 @@ en:
legislation:
draft_versions:
changes:
title: Changes
see_text: See text
show:
see_changes: See changes
processes:
debate:
empty_questions: There aren't any questions
participate: Participate in the debate
header_full:
title: Participate
description: Description
target: Target
how_to_participate: How to participate
more_info: More information and context
index:
hightlighted_processes: HIGHLIGHTED PROCESSES
filters:
open: Open processes
next: Next
past: Past
phase_not_open:
not_open: This phase is not open yet
phase_draft_publication:
empty: There are no drafts published
phase_allegations:
empty: There are no drafts published
phase_final_version_publication:
empty: Results have not been published yet
process:
see_latest_comments: See latest comments
see_latest_comments_title: Comment on this process
shared:
key_dates: "Key dates:"
debate_dates: Debate
draft_publication_date: Draft publication
allegations_dates: Allegations
final_publication_date: Final result publication
questions:
question:
comments:
zero: No comments
one: "%{count} comment"
other: "%{count} comments"
debate: Debate
show:
comments: Comments
next_question: Next question
share: Share
share_twitter: Share on Twitter
share_facebook: Share on Facebook
share_gplus: Share on Google+
title: Collaborative legislation process
locale: English
notifications:
index:
@@ -457,6 +506,7 @@ en:
districts_list: "Districts list"
categories: "Categories"
target_blank_html: " (link opens in new window)"
you_are_in: "You are in"
unflag: Unflag
outline:
debates: Debates

View File

@@ -190,6 +190,7 @@ es:
debates: Debates
external_link_blog: Blog
external_link_opendata: Datos abiertos
external_link_opendata_url: "/opendata"
external_link_transparency: Transparencia
external_link_transparency_url: https://transparency.consul
locale: 'Idioma:'
@@ -208,7 +209,6 @@ es:
open: abierto
open_city_slogan_html: Existen ciudades gobernadas directamente por sus habitantes, que <strong>debaten</strong> sobre temas que les preocupan, <strong>proponen</strong> ideas para mejorar sus vidas y <strong>deciden</strong> entre todas y todos las que se llevan a cabo.
open_city_title: La ciudad que quieres será la ciudad que quieras.
open_data: Datos abiertos
open_gov: Gobierno %{open}
proposals: Propuestas
proposal_ballot: Votaciones
@@ -224,9 +224,58 @@ es:
legislation:
draft_versions:
changes:
title: Cambios
see_text: Ver texto
show:
see_changes: Ver cambios
processes:
debate:
empty_questions: No hay preguntas
participate: Realiza tus aportaciones al debate previo participando en los siguientes temas.
header_full:
title: Colabora en la elaboración de la normativa sobre
description: En qué consiste
target: A quién va dirigido
how_to_participate: Cómo puedes participar
more_info: Más información y contexto
index:
hightlighted_processes: PROCESOS DESTACADOS
filters:
open: Procesos activos
next: Próximamente
past: Terminados
phase_not_open:
not_open: Esta fase del proceso todavía no está abierta
phase_draft_publication:
empty: No se ha publicado ningún borrador
phase_allegations:
empty: No se ha publicado ningún borrador
phase_final_version_publication:
empty: No se ha publicado el resultado todavía
process:
see_latest_comments: Ver últimas aportaciones
see_latest_comments_title: Aportar a este proceso
shared:
key_dates: "Fechas clave:"
debate_dates: Debate previo
draft_publication_date: Publicación borrador
allegations_dates: Alegaciones
final_publication_date: Publicación resultados
questions:
question:
comments:
zero: Sin comentarios
one: "%{count} comentario"
other: "%{count} comentarios"
debate: Debate
show:
comments: Comentarios
next_question: Siguiente pregunta
share: Compartir
share_twitter: Compartir en Twitter
share_facebook: Compartir en Facebook
share_gplus: Compartir en Google+
title: Proceso de legislación colaborativa
locale: Español
notifications:
index:
@@ -457,6 +506,7 @@ es:
districts_list: "Listado de distritos"
categories: "Categorías"
target_blank_html: " (se abre en ventana nueva)"
you_are_in: "Estás en"
unflag: Deshacer denuncia
outline:
debates: Debates

View File

@@ -92,9 +92,15 @@ Rails.application.routes.draw do
namespace :legislation do
resources :processes, only: [:index, :show] do
get :draft_publication
get :allegations
get :final_version_publication
resources :questions, only: [:show] do
resources :answers, only: [:create]
end
resources :draft_versions, only: [:show] do
resources :annotations
get :changes
resources :annotations
end
end
end
@@ -205,6 +211,7 @@ Rails.application.routes.draw do
namespace :legislation do
resources :processes do
resources :questions
resources :draft_versions
end
end

View File

@@ -0,0 +1,23 @@
class CreateLegislationQuestions < ActiveRecord::Migration
def change
create_table :legislation_questions do |t|
t.references :legislation_process, index: true
t.text :title
t.integer :answers_count, default: 0
t.datetime :hidden_at, index: true
t.timestamps null: false
end
create_table :legislation_question_options do |t|
t.references :legislation_question, index: true
t.string :value
t.integer :answers_count, default: 0
t.datetime :hidden_at, index: true
t.timestamps null: false
end
end
end

View File

@@ -0,0 +1,5 @@
class AddCommentsCountToLegislationQuestions < ActiveRecord::Migration
def change
add_column :legislation_questions, :comments_count, :integer, default: 0
end
end

View File

@@ -0,0 +1,5 @@
class AddAuthorToLegislationQuestions < ActiveRecord::Migration
def change
add_column :legislation_questions, :author_id, :integer
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161213144031) do
ActiveRecord::Schema.define(version: 20161222180927) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -54,8 +54,8 @@ ActiveRecord::Schema.define(version: 20161213144031) do
t.string "quote"
t.text "ranges"
t.text "text"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.integer "legacy_legislation_id"
end
@@ -274,6 +274,32 @@ ActiveRecord::Schema.define(version: 20161213144031) do
add_index "legislation_processes", ["hidden_at"], name: "index_legislation_processes_on_hidden_at", using: :btree
add_index "legislation_processes", ["start_date"], name: "index_legislation_processes_on_start_date", using: :btree
create_table "legislation_question_options", force: :cascade do |t|
t.integer "legislation_question_id"
t.string "value"
t.integer "answers_count", default: 0
t.datetime "hidden_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "legislation_question_options", ["hidden_at"], name: "index_legislation_question_options_on_hidden_at", using: :btree
add_index "legislation_question_options", ["legislation_question_id"], name: "index_legislation_question_options_on_legislation_question_id", using: :btree
create_table "legislation_questions", force: :cascade do |t|
t.integer "legislation_process_id"
t.text "title"
t.integer "answers_count", default: 0
t.datetime "hidden_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "comments_count", default: 0
t.integer "author_id"
end
add_index "legislation_questions", ["hidden_at"], name: "index_legislation_questions_on_hidden_at", using: :btree
add_index "legislation_questions", ["legislation_process_id"], name: "index_legislation_questions_on_legislation_process_id", using: :btree
create_table "locks", force: :cascade do |t|
t.integer "user_id"
t.integer "tries", default: 0

View File

@@ -349,14 +349,36 @@ FactoryGirl.define do
description "Description of the process"
target "Who will affected by this law?"
how_to_participate "You can participate by answering some questions"
start_date "2016-11-16"
end_date "2016-11-16"
debate_start_date "2016-11-16"
debate_end_date "2016-11-16"
draft_publication_date "2016-11-16"
allegations_start_date "2016-11-16"
allegations_end_date "2016-11-16"
final_publication_date "2016-11-16"
start_date Date.current - 5.days
end_date Date.current + 5.days
debate_start_date Date.current - 5.days
debate_end_date Date.current - 2.days
draft_publication_date Date.current - 1.day
allegations_start_date Date.current
allegations_end_date Date.current + 3.days
final_publication_date Date.current + 5.days
trait :next do
start_date Date.current + 2.days
end_date Date.current + 8.days
debate_start_date Date.current + 2.days
debate_end_date Date.current + 4.days
draft_publication_date Date.current + 5.day
allegations_start_date Date.current + 5.days
allegations_end_date Date.current + 7.days
final_publication_date Date.current + 8.days
end
trait :past do
start_date Date.current - 12.days
end_date Date.current - 2.days
debate_start_date Date.current - 12.days
debate_end_date Date.current - 9.days
draft_publication_date Date.current - 8.day
allegations_start_date Date.current - 8.days
allegations_end_date Date.current - 4.days
final_publication_date Date.current - 2.days
end
end
factory :legislation_draft_version, class: 'Legislation::DraftVersion' do
@@ -367,4 +389,15 @@ FactoryGirl.define do
final_version false
body "Body of the legislation text"
end
factory :legislation_question, class: 'Legislation::Question' do
process factory: :legislation_process
title "Question text"
author factory: :user
end
factory :legislation_question_option, class: 'Legislation::QuestionOption' do
question factory: :legislation_question
sequence(:value) { |n| "Option #{n}" }
end
end

View File

@@ -0,0 +1,89 @@
require 'rails_helper'
feature 'Admin legislation questions' do
background do
admin = create(:administrator)
login_as(admin.user)
end
context "Feature flag" do
scenario 'Disabled with a feature flag' do
Setting['feature.legislation'] = nil
process = create(:legislation_process)
expect{ visit admin_legislation_process_questions_path(process) }.to raise_exception(FeatureFlags::FeatureDisabled)
end
end
context "Index" do
scenario 'Displaying legislation process questions' do
process = create(:legislation_process, title: 'An example legislation process')
question = create(:legislation_question, process: process, title: 'Question 1')
question = create(:legislation_question, process: process, title: 'Question 2')
visit admin_legislation_processes_path(filter: 'all')
click_link 'An example legislation process'
click_link 'Debate'
expect(page).to have_content('Question 1')
expect(page).to have_content('Question 2')
end
end
context 'Create' do
scenario 'Valid legislation question' do
process = create(:legislation_process, title: 'An example legislation process')
visit admin_root_path
within('#side_menu') do
click_link "Collaborative Legislation"
end
click_link "All"
expect(page).to have_content 'An example legislation process'
click_link 'An example legislation process'
click_link 'Debate'
click_link 'Create question'
fill_in 'legislation_question_title', with: 'Question 3'
click_button 'Create question'
expect(page).to have_content 'Question 3'
end
end
context 'Update' do
scenario 'Valid legislation question', :js do
process = create(:legislation_process, title: 'An example legislation process')
question = create(:legislation_question, title: 'Question 2', process: process)
visit admin_root_path
within('#side_menu') do
click_link "Collaborative Legislation"
end
click_link "All"
expect(page).to have_content 'An example legislation process'
click_link 'An example legislation process'
click_link 'Debate'
click_link 'Question 2'
fill_in 'legislation_question_title', with: 'Question 2b'
click_button 'Save changes'
expect(page).to have_content 'Question 2b'
end
end
end

View File

@@ -0,0 +1,509 @@
require 'rails_helper'
include ActionView::Helpers::DateHelper
feature 'Commenting legislation questions' do
let(:user) { create :user }
let(:legislation_question) { create :legislation_question }
scenario 'Index' do
3.times { create(:comment, commentable: legislation_question) }
visit legislation_process_question_path(legislation_question.process, legislation_question)
expect(page).to have_css('.comment', count: 3)
comment = Comment.last
within first('.comment') do
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 comment.body
end
end
scenario 'Show' do
parent_comment = create(:comment, commentable: legislation_question)
first_child = create(:comment, commentable: legislation_question, parent: parent_comment)
second_child = create(:comment, commentable: legislation_question, parent: parent_comment)
visit comment_path(parent_comment)
expect(page).to have_css(".comment", count: 3)
expect(page).to have_content parent_comment.body
expect(page).to have_content first_child.body
expect(page).to have_content second_child.body
expect(page).to have_link "Go back to #{legislation_question.title}", href: legislation_process_question_path(legislation_question.process, legislation_question)
end
scenario 'Collapsable comments', :js do
parent_comment = create(:comment, body: "Main comment", commentable: legislation_question)
child_comment = create(:comment, body: "First subcomment", commentable: legislation_question, parent: parent_comment)
grandchild_comment = create(:comment, body: "Last subcomment", commentable: legislation_question, parent: child_comment)
visit legislation_process_question_path(legislation_question.process, legislation_question)
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).to_not 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).to_not have_content child_comment.body
expect(page).to_not have_content grandchild_comment.body
end
scenario 'Comment order' do
c1 = create(:comment, :with_confidence_score, commentable: legislation_question, cached_votes_up: 100, cached_votes_total: 120, created_at: Time.current - 2)
c2 = create(:comment, :with_confidence_score, commentable: legislation_question, cached_votes_up: 10, cached_votes_total: 12, created_at: Time.current - 1)
c3 = create(:comment, :with_confidence_score, commentable: legislation_question, cached_votes_up: 1, cached_votes_total: 2, created_at: Time.current)
visit legislation_process_question_path(legislation_question.process, legislation_question, order: :most_voted)
expect(c1.body).to appear_before(c2.body)
expect(c2.body).to appear_before(c3.body)
visit legislation_process_question_path(legislation_question.process, legislation_question, order: :newest)
expect(c3.body).to appear_before(c2.body)
expect(c2.body).to appear_before(c1.body)
visit legislation_process_question_path(legislation_question.process, legislation_question, order: :oldest)
expect(c1.body).to appear_before(c2.body)
expect(c2.body).to appear_before(c3.body)
end
scenario 'Creation date works differently in roots and in child comments, even when sorting by confidence_score' do
old_root = create(:comment, commentable: legislation_question, created_at: Time.current - 10)
new_root = create(:comment, commentable: legislation_question, created_at: Time.current)
old_child = create(:comment, commentable: legislation_question, parent_id: new_root.id, created_at: Time.current - 10)
new_child = create(:comment, commentable: legislation_question, parent_id: new_root.id, created_at: Time.current)
visit legislation_process_question_path(legislation_question.process, legislation_question, order: :most_voted)
expect(new_root.body).to appear_before(old_root.body)
expect(old_child.body).to appear_before(new_child.body)
visit legislation_process_question_path(legislation_question.process, legislation_question, order: :newest)
expect(new_root.body).to appear_before(old_root.body)
expect(new_child.body).to appear_before(old_child.body)
visit legislation_process_question_path(legislation_question.process, legislation_question, order: :oldest)
expect(old_root.body).to appear_before(new_root.body)
expect(old_child.body).to appear_before(new_child.body)
end
scenario 'Turns links into html links' do
create :comment, commentable: legislation_question, body: 'Built with http://rubyonrails.org/'
visit legislation_process_question_path(legislation_question.process, legislation_question)
within first('.comment') do
expect(page).to have_content 'Built with 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
create :comment, commentable: legislation_question, body: "<script>alert('hola')</script> <a href=\"javascript:alert('sorpresa!')\">click me<a/> http://www.url.com"
visit legislation_process_question_path(legislation_question.process, legislation_question)
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 { create(:comment, commentable: legislation_question)}
visit legislation_process_question_path(legislation_question.process, legislation_question)
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).to_not have_content("3")
click_link "Next", exact: false
end
expect(page).to have_css('.comment', count: 2)
end
feature 'Not logged user' do
scenario 'can not see comments forms' do
create(:comment, commentable: legislation_question)
visit legislation_process_question_path(legislation_question.process, legislation_question)
expect(page).to have_content 'You must Sign in or Sign up to leave a comment'
within('#comments') do
expect(page).to_not have_content 'Write a comment'
expect(page).to_not have_content 'Reply'
end
end
end
scenario 'Create', :js do
login_as(user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
fill_in "comment-body-legislation_question_#{legislation_question.id}", with: 'Have you thought about...?'
click_button 'Publish comment'
within "#comments" do
expect(page).to have_content 'Have you thought about...?'
expect(page).to have_content '(1)'
end
end
scenario 'Errors on create', :js do
login_as(user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
click_button 'Publish comment'
expect(page).to have_content "Can't be blank"
end
scenario 'Reply', :js do
citizen = create(:user, username: 'Ana')
manuela = create(:user, username: 'Manuela')
comment = create(:comment, commentable: legislation_question, user: citizen)
login_as(manuela)
visit legislation_process_question_path(legislation_question.process, legislation_question)
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).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
end
scenario 'Errors on reply', :js do
comment = create(:comment, commentable: legislation_question, user: user)
login_as(user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
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 "N replies", :js do
parent = create(:comment, commentable: legislation_question)
7.times do
create(:comment, commentable: legislation_question, parent: parent)
parent = parent.children.first
end
visit legislation_process_question_path(legislation_question.process, legislation_question)
expect(page).to have_css(".comment.comment.comment.comment.comment.comment.comment.comment")
end
scenario "Flagging as inappropriate", :js do
comment = create(:comment, commentable: legislation_question)
login_as(user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
within "#comment_#{comment.id}" do
page.find("#flag-expand-comment-#{comment.id}").click
page.find("#flag-comment-#{comment.id}").click
expect(page).to have_css("#unflag-expand-comment-#{comment.id}")
end
expect(Flag.flagged?(user, comment)).to be
end
scenario "Undoing flagging as inappropriate", :js do
comment = create(:comment, commentable: legislation_question)
Flag.flag(user, comment)
login_as(user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
within "#comment_#{comment.id}" do
page.find("#unflag-expand-comment-#{comment.id}").click
page.find("#unflag-comment-#{comment.id}").click
expect(page).to have_css("#flag-expand-comment-#{comment.id}")
end
expect(Flag.flagged?(user, comment)).to_not be
end
scenario "Flagging turbolinks sanity check", :js do
legislation_question = create(:legislation_question, title: "Should we change the world?")
comment = create(:comment, commentable: legislation_question)
login_as(user)
visit legislation_process_path(legislation_question.process)
click_link "Should we change the world?"
within "#comment_#{comment.id}" do
page.find("#flag-expand-comment-#{comment.id}").click
expect(page).to have_selector("#flag-comment-#{comment.id}")
end
end
scenario "Erasing a comment's author" do
legislation_question = create(:legislation_question)
comment = create(:comment, commentable: legislation_question, body: 'this should be visible')
comment.user.erase
visit legislation_process_question_path(legislation_question.process, legislation_question)
within "#comment_#{comment.id}" do
expect(page).to have_content('User deleted')
expect(page).to have_content('this should be visible')
end
end
scenario 'Submit button is disabled after clicking', :js do
legislation_question = create(:legislation_question)
login_as(user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
fill_in "comment-body-legislation_question_#{legislation_question.id}", with: 'Testing submit button!'
click_button 'Publish comment'
# The button's text should now be "..."
# This should be checked before the Ajax request is finished
expect(page).to_not have_button 'Publish comment'
expect(page).to have_content('Testing submit button!')
end
feature "Moderators" do
scenario "can create comment as a moderator", :js do
moderator = create(:moderator)
login_as(moderator.user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
fill_in "comment-body-legislation_question_#{legislation_question.id}", with: "I am moderating!"
check "comment-as-moderator-legislation_question_#{legislation_question.id}"
click_button "Publish comment"
within "#comments" do
expect(page).to have_content "I am moderating!"
expect(page).to have_content "Moderator ##{moderator.id}"
expect(page).to have_css "div.is-moderator"
expect(page).to have_css "img.moderator-avatar"
end
end
scenario "can create reply as a moderator", :js do
citizen = create(:user, username: "Ana")
manuela = create(:user, username: "Manuela")
moderator = create(:moderator, user: manuela)
comment = create(:comment, commentable: legislation_question, user: citizen)
login_as(manuela)
visit legislation_process_question_path(legislation_question.process, legislation_question)
click_link "Reply"
within "#js-comment-form-comment_#{comment.id}" do
fill_in "comment-body-comment_#{comment.id}", with: "I am moderating!"
check "comment-as-moderator-comment_#{comment.id}"
click_button 'Publish reply'
end
within "#comment_#{comment.id}" do
expect(page).to have_content "I am moderating!"
expect(page).to have_content "Moderator ##{moderator.id}"
expect(page).to have_css "div.is-moderator"
expect(page).to have_css "img.moderator-avatar"
end
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
end
scenario "can not comment as an administrator" do
moderator = create(:moderator)
login_as(moderator.user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
expect(page).to_not have_content "Comment as administrator"
end
end
feature "Administrators" do
scenario "can create comment as an administrator", :js do
admin = create(:administrator)
login_as(admin.user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
fill_in "comment-body-legislation_question_#{legislation_question.id}", with: "I am your Admin!"
check "comment-as-administrator-legislation_question_#{legislation_question.id}"
click_button "Publish comment"
within "#comments" do
expect(page).to have_content "I am your Admin!"
expect(page).to have_content "Administrator ##{admin.id}"
expect(page).to have_css "div.is-admin"
expect(page).to have_css "img.admin-avatar"
end
end
scenario "can create reply as an administrator", :js do
citizen = create(:user, username: "Ana")
manuela = create(:user, username: "Manuela")
admin = create(:administrator, user: manuela)
comment = create(:comment, commentable: legislation_question, user: citizen)
login_as(manuela)
visit legislation_process_question_path(legislation_question.process, legislation_question)
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.id}"
expect(page).to have_css "div.is-admin"
expect(page).to have_css "img.admin-avatar"
end
expect(page).to_not have_selector("#js-comment-form-comment_#{comment.id}", visible: true)
end
scenario "can not comment as a moderator" do
admin = create(:administrator)
login_as(admin.user)
visit legislation_process_question_path(legislation_question.process, legislation_question)
expect(page).to_not have_content "Comment as moderator"
end
end
feature 'Voting comments' do
background do
@manuela = create(:user, verified_at: Time.current)
@pablo = create(:user)
@legislation_question = create(:legislation_question)
@comment = create(:comment, commentable: @legislation_question)
login_as(@manuela)
end
scenario 'Show' do
create(:vote, voter: @manuela, votable: @comment, vote_flag: true)
create(:vote, voter: @pablo, votable: @comment, vote_flag: false)
visit legislation_process_question_path(@legislation_question.process, @legislation_question)
within("#comment_#{@comment.id}_votes") do
within(".in_favor") do
expect(page).to have_content "1"
end
within(".against") do
expect(page).to have_content "1"
end
expect(page).to have_content "2 votes"
end
end
scenario 'Create', :js do
visit legislation_process_question_path(@legislation_question.process, @legislation_question)
within("#comment_#{@comment.id}_votes") do
find(".in_favor a").click
within(".in_favor") do
expect(page).to have_content "1"
end
within(".against") do
expect(page).to have_content "0"
end
expect(page).to have_content "1 vote"
end
end
scenario 'Update', :js do
visit legislation_process_question_path(@legislation_question.process, @legislation_question)
within("#comment_#{@comment.id}_votes") do
find('.in_favor a').click
find('.against a').click
within('.in_favor') do
expect(page).to have_content "0"
end
within('.against') do
expect(page).to have_content "1"
end
expect(page).to have_content "1 vote"
end
end
xscenario 'Trying to vote multiple times', :js do
visit legislation_process_question_path(@legislation_question.process, @legislation_question)
within("#comment_#{@comment.id}_votes") do
find('.in_favor a').click
within('.in_favor') do
expect(page).to have_content "1"
end
find('.in_favor a').click
within('.in_favor') do
expect(page).to_not have_content "2"
expect(page).to have_content "1"
end
within('.against') do
expect(page).to have_content "0"
end
expect(page).to have_content "1 vote"
end
end
end
end

View File

@@ -232,7 +232,7 @@ feature 'Debates' do
expect(page).to have_content 'Debate created successfully.'
within "#tags" do
within "#tags_debate_#{Debate.last.id}" do
expect(page).to have_content 'Education'
expect(page).to_not have_content 'Health'
end
@@ -249,7 +249,8 @@ feature 'Debates' do
click_button 'Start a debate'
expect(page).to have_content 'Debate created successfully.'
within "#tags" do
within "#tags_debate_#{Debate.last.id}" do
expect(page).to have_content 'Refugees'
expect(page).to have_content 'Solidarity'
end

View File

@@ -0,0 +1,36 @@
require 'rails_helper'
feature 'Legislation' do
context 'process debate page' do
scenario 'shows question list' do
process = create(:legislation_process, debate_start_date: Date.current - 1.day, debate_end_date: Date.current + 2.days)
create(:legislation_question, process: process, title: "Question 1")
create(:legislation_question, process: process, title: "Question 2")
create(:legislation_question, process: process, title: "Question 3")
visit legislation_process_path(process)
expect(page).to have_content("Participate in the debate")
expect(page).to have_content("Question 1")
expect(page).to have_content("Question 2")
expect(page).to have_content("Question 3")
click_link "Question 1"
expect(page).to have_content("Question 1")
expect(page).to have_content("Next question")
click_link "Next question"
expect(page).to have_content("Question 2")
expect(page).to have_content("Next question")
click_link "Next question"
expect(page).to have_content("Question 3")
expect(page).to_not have_content("Next question")
end
end
end

View File

@@ -0,0 +1,112 @@
require 'rails_helper'
feature 'Legislation' do
context 'processes home page' do
scenario 'Processes can be listed' do
processes = create_list(:legislation_process, 3)
visit legislation_processes_path
processes.each do |process|
expect(page).to have_link(process.title)
end
end
scenario 'Filtering processes' do
create(:legislation_process, title: "Process open")
create(:legislation_process, :next, title: "Process next")
create(:legislation_process, :past, title: "Process past")
visit legislation_processes_path
expect(page).to have_content('Process open')
expect(page).to_not have_content('Process next')
expect(page).to_not have_content('Process past')
visit legislation_processes_path(filter: 'next')
expect(page).to_not have_content('Process open')
expect(page).to have_content('Process next')
expect(page).to_not have_content('Process past')
visit legislation_processes_path(filter: 'past')
expect(page).to_not have_content('Process open')
expect(page).to_not have_content('Process next')
expect(page).to have_content('Process past')
end
end
context 'process page' do
context 'debate phase' do
scenario 'not open' do
process = create(:legislation_process, debate_start_date: Date.current + 1.day, debate_end_date: Date.current + 2.days)
visit legislation_process_path(process)
expect(page).to have_content("This phase is not open yet")
end
scenario 'open' do
process = create(:legislation_process, debate_start_date: Date.current - 1.day, debate_end_date: Date.current + 2.days)
visit legislation_process_path(process)
expect(page).to have_content("Participate in the debate")
end
end
context 'draft publication phase' do
scenario 'not open' do
process = create(:legislation_process, draft_publication_date: Date.current + 1.day)
visit legislation_process_draft_publication_path(process)
expect(page).to have_content("This phase is not open yet")
end
scenario 'open' do
process = create(:legislation_process, draft_publication_date: Date.current)
visit legislation_process_draft_publication_path(process)
expect(page).to have_content("There are no drafts published")
end
end
context 'allegations phase' do
scenario 'not open' do
process = create(:legislation_process, allegations_start_date: Date.current + 1.day, allegations_end_date: Date.current + 2.days)
visit legislation_process_allegations_path(process)
expect(page).to have_content("This phase is not open yet")
end
scenario 'open' do
process = create(:legislation_process, allegations_start_date: Date.current - 1.day, allegations_end_date: Date.current + 2.days)
visit legislation_process_allegations_path(process)
expect(page).to have_content("There are no drafts published")
end
end
context 'final version publication phase' do
scenario 'not open' do
process = create(:legislation_process, final_publication_date: Date.current + 1.day)
visit legislation_process_final_version_publication_path(process)
expect(page).to have_content("This phase is not open yet")
end
scenario 'open' do
process = create(:legislation_process, final_publication_date: Date.current)
visit legislation_process_final_version_publication_path(process)
expect(page).to have_content("Results have not been published yet")
end
end
end
end

View File

@@ -333,7 +333,7 @@ feature 'Proposals' do
expect(page).to have_content 'Proposal created successfully.'
within "#tags" do
within "#tags_proposal_#{Proposal.last.id}" do
expect(page).to have_content 'Education'
expect(page).to_not have_content 'Health'
end
@@ -355,7 +355,7 @@ feature 'Proposals' do
click_button 'Create proposal'
expect(page).to have_content 'Proposal created successfully.'
within "#tags" do
within "#tags_proposal_#{Proposal.last.id}" do
expect(page).to have_content 'Refugees'
expect(page).to have_content 'Solidarity'
end

View File

@@ -12,6 +12,7 @@ describe "Abilities::Administrator" do
let(:debate) { create(:debate) }
let(:comment) { create(:comment) }
let(:proposal) { create(:proposal) }
let(:legislation_question) { create(:legislation_question) }
let(:hidden_debate) { create(:debate, :hidden) }
let(:hidden_comment) { create(:comment, :hidden) }
@@ -50,6 +51,9 @@ describe "Abilities::Administrator" do
it { should be_able_to(:comment_as_administrator, proposal) }
it { should_not be_able_to(:comment_as_moderator, proposal) }
it { should be_able_to(:comment_as_administrator, legislation_question) }
it { should_not be_able_to(:comment_as_moderator, legislation_question) }
it { should be_able_to(:manage, Annotation) }
it { should be_able_to(:read, SpendingProposal) }

View File

@@ -11,6 +11,7 @@ describe "Abilities::Moderator" do
let(:debate) { create(:debate) }
let(:comment) { create(:comment) }
let(:proposal) { create(:proposal) }
let(:legislation_question) { create(:legislation_question) }
let(:own_debate) { create(:debate, author: user) }
let(:own_comment) { create(:comment, author: user) }
@@ -101,7 +102,9 @@ describe "Abilities::Moderator" do
it { should be_able_to(:comment_as_moderator, debate) }
it { should be_able_to(:comment_as_moderator, proposal) }
it { should be_able_to(:comment_as_moderator, legislation_question) }
it { should_not be_able_to(:comment_as_administrator, debate) }
it { should_not be_able_to(:comment_as_administrator, proposal) }
it { should_not be_able_to(:comment_as_administrator, legislation_question) }
end
end

View File

@@ -14,7 +14,7 @@ RSpec.describe Legislation::Process, type: :model do
@process_3 = create(:legislation_process, start_date: Date.current - 4.days, end_date: Date.current - 3.days)
end
it "filter open" do
it "filters open" do
open_processes = ::Legislation::Process.open
expect(open_processes).to include(@process_1)
@@ -22,7 +22,7 @@ RSpec.describe Legislation::Process, type: :model do
expect(open_processes).to_not include(@process_3)
end
it "filter next" do
it "filters next" do
next_processes = ::Legislation::Process.next
expect(next_processes).to include(@process_2)
@@ -30,7 +30,7 @@ RSpec.describe Legislation::Process, type: :model do
expect(next_processes).to_not include(@process_3)
end
it "filter past" do
it "filters past" do
past_processes = ::Legislation::Process.past
expect(past_processes).to include(@process_3)
@@ -38,4 +38,152 @@ RSpec.describe Legislation::Process, type: :model do
expect(past_processes).to_not include(@process_1)
end
end
describe "#open_phase?" do
it "checks debate phase" do
process = create(:legislation_process)
# future
process.update_attributes(debate_start_date: Date.current + 2.days, debate_end_date: Date.current + 3.days)
expect(process.open_phase?(:debate)).to be false
# started
process.update_attributes(debate_start_date: Date.current - 2.days, debate_end_date: Date.current + 1.day)
expect(process.open_phase?(:debate)).to be true
# starts today
process.update_attributes(debate_start_date: Date.current, debate_end_date: Date.current + 1.day)
expect(process.open_phase?(:debate)).to be true
# past
process.update_attributes(debate_start_date: Date.current - 2.days, debate_end_date: Date.current - 1.day)
expect(process.open_phase?(:debate)).to be false
end
it "checks allegations phase" do
process = create(:legislation_process)
# future
process.update_attributes(allegations_start_date: Date.current + 2.days, allegations_end_date: Date.current + 3.days)
expect(process.open_phase?(:allegations)).to be false
# started
process.update_attributes(allegations_start_date: Date.current - 2.days, allegations_end_date: Date.current + 1.day)
expect(process.open_phase?(:allegations)).to be true
# starts today
process.update_attributes(allegations_start_date: Date.current, allegations_end_date: Date.current + 1.day)
expect(process.open_phase?(:allegations)).to be true
# past
process.update_attributes(allegations_start_date: Date.current - 2.days, allegations_end_date: Date.current - 1.day)
expect(process.open_phase?(:allegations)).to be false
end
it "checks draft publication phase" do
process = create(:legislation_process)
# future
process.update_attributes(draft_publication_date: Date.current + 2.days)
expect(process.open_phase?(:draft_publication)).to be false
# past
process.update_attributes(draft_publication_date: Date.current - 2.days)
expect(process.open_phase?(:draft_publication)).to be true
# starts today
process.update_attributes(draft_publication_date: Date.current)
expect(process.open_phase?(:draft_publication)).to be true
end
it "checks final version publication phase" do
process = create(:legislation_process)
# future
process.update_attributes(final_publication_date: Date.current + 2.days)
expect(process.open_phase?(:final_version_publication)).to be false
# past
process.update_attributes(final_publication_date: Date.current - 2.days)
expect(process.open_phase?(:final_version_publication)).to be true
# starts today
process.update_attributes(final_publication_date: Date.current)
expect(process.open_phase?(:final_version_publication)).to be true
end
end
describe "#show_phase?" do
it "checks debate phase" do
process = create(:legislation_process)
# future
process.update_attributes(debate_start_date: Date.current + 2.days, debate_end_date: Date.current + 3.days)
expect(process.show_phase?(:debate)).to be false
# started
process.update_attributes(debate_start_date: Date.current - 2.days, debate_end_date: Date.current + 1.day)
expect(process.show_phase?(:debate)).to be true
# starts today
process.update_attributes(debate_start_date: Date.current, debate_end_date: Date.current + 1.day)
expect(process.show_phase?(:debate)).to be true
# past
process.update_attributes(debate_start_date: Date.current - 2.days, debate_end_date: Date.current - 1.day)
expect(process.show_phase?(:debate)).to be true
end
it "checks allegations phase" do
process = create(:legislation_process)
# future
process.update_attributes(allegations_start_date: Date.current + 2.days, allegations_end_date: Date.current + 3.days)
expect(process.show_phase?(:allegations)).to be false
# started
process.update_attributes(allegations_start_date: Date.current - 2.days, allegations_end_date: Date.current + 1.day)
expect(process.show_phase?(:allegations)).to be true
# starts today
process.update_attributes(allegations_start_date: Date.current, allegations_end_date: Date.current + 1.day)
expect(process.show_phase?(:allegations)).to be true
# past
process.update_attributes(allegations_start_date: Date.current - 2.days, allegations_end_date: Date.current - 1.day)
expect(process.show_phase?(:allegations)).to be true
end
it "checks draft publication phase" do
process = create(:legislation_process)
# future
process.update_attributes(draft_publication_date: Date.current + 2.days)
expect(process.show_phase?(:draft_publication)).to be false
# past
process.update_attributes(draft_publication_date: Date.current - 2.days)
expect(process.show_phase?(:draft_publication)).to be true
# starts today
process.update_attributes(draft_publication_date: Date.current)
expect(process.show_phase?(:draft_publication)).to be true
end
it "checks final version publication phase" do
process = create(:legislation_process)
# future
process.update_attributes(final_publication_date: Date.current + 2.days)
expect(process.show_phase?(:final_version_publication)).to be false
# past
process.update_attributes(final_publication_date: Date.current - 2.days)
expect(process.show_phase?(:final_version_publication)).to be true
# starts today
process.update_attributes(final_publication_date: Date.current)
expect(process.show_phase?(:final_version_publication)).to be true
end
end
end

View File

@@ -0,0 +1,18 @@
require 'rails_helper'
RSpec.describe Legislation::QuestionOption, type: :model do
let(:legislation_question_option) { build(:legislation_question_option) }
it "should be valid" do
expect(legislation_question_option).to be_valid
end
it "should be unique per question" do
question = create(:legislation_question)
valid_question_option = create(:legislation_question_option, question: question, value: "uno")
invalid_question_option = build(:legislation_question_option, question: question, value: "uno")
expect(invalid_question_option).to_not be_valid
end
end

View File

@@ -0,0 +1,9 @@
require 'rails_helper'
RSpec.describe Legislation::Question, type: :model do
let(:legislation_question) { build(:legislation_question) }
it "should be valid" do
expect(legislation_question).to be_valid
end
end