Merge pull request #4065 from consul/legislation_summary
Add collaborative legislation summary
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -10,6 +10,8 @@ gem "ancestry", "~> 3.0.7"
|
||||
gem "audited", "~> 4.9.0"
|
||||
gem "autoprefixer-rails", "~> 8.2.0"
|
||||
gem "cancancan", "~> 2.3.0"
|
||||
gem "caxlsx", "~> 3.0.2"
|
||||
gem "caxlsx_rails", "~> 0.6.2"
|
||||
gem "ckeditor", "~> 4.3.0"
|
||||
gem "cocoon", "~> 1.2.14"
|
||||
gem "daemons", "~> 1.3.1"
|
||||
|
||||
10
Gemfile.lock
10
Gemfile.lock
@@ -131,6 +131,14 @@ GEM
|
||||
rack (>= 1.4)
|
||||
rack-proxy (>= 0.6.0)
|
||||
selenium-webdriver (~> 3.0)
|
||||
caxlsx (3.0.2)
|
||||
htmlentities (~> 4.3, >= 4.3.4)
|
||||
mimemagic (~> 0.3)
|
||||
nokogiri (~> 1.10, >= 1.10.4)
|
||||
rubyzip (>= 1.3.0, < 3)
|
||||
caxlsx_rails (0.6.2)
|
||||
actionpack (>= 3.1)
|
||||
caxlsx (>= 3.0)
|
||||
chef-utils (16.4.41)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
@@ -638,6 +646,8 @@ DEPENDENCIES
|
||||
capistrano3-puma (~> 4.0.0)
|
||||
capybara (~> 3.29.0)
|
||||
capybara-webmock (~> 0.5.5)
|
||||
caxlsx (~> 3.0.2)
|
||||
caxlsx_rails (~> 0.6.2)
|
||||
ckeditor (~> 4.3.0)
|
||||
cocoon (~> 1.2.14)
|
||||
coveralls (~> 0.8.22)
|
||||
|
||||
@@ -2045,10 +2045,6 @@ table {
|
||||
padding: $line-height / 4;
|
||||
position: relative;
|
||||
|
||||
.relative {
|
||||
padding-left: rem-calc(18);
|
||||
}
|
||||
|
||||
.divider {
|
||||
color: $text-light;
|
||||
display: inline-block;
|
||||
@@ -2060,24 +2056,23 @@ table {
|
||||
}
|
||||
|
||||
.responses-count {
|
||||
.far {
|
||||
@extend .fa-minus-square;
|
||||
font-size: $small-font-size;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
text-decoration: none;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
.show-children {
|
||||
@include has-fa-icon(plus-square, r);
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
.far {
|
||||
@extend .fa-plus-square;
|
||||
.collapse-children {
|
||||
@include has-fa-icon(minus-square, r);
|
||||
}
|
||||
|
||||
.show-children::before,
|
||||
.collapse-children::before {
|
||||
margin-right: rem-calc(6);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
&.collapsed {
|
||||
|
||||
.collapse-children {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1006,3 +1006,91 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
// 10. Legislation summary
|
||||
// -------------------------
|
||||
|
||||
.process-summary {
|
||||
> section {
|
||||
@include grid-row;
|
||||
margin-top: $line-height * 1.5;
|
||||
padding: 0 rem-calc(16);
|
||||
|
||||
> header {
|
||||
background: none;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
h4,
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
> section > header,
|
||||
.question-title,
|
||||
.annotation-title,
|
||||
.comment-summary,
|
||||
.proposal-summary {
|
||||
@include breakpoint(medium) {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
|
||||
> :first-child {
|
||||
$margin: rem-calc(map-get($grid-column-gutter, "medium"));
|
||||
|
||||
margin-right: $margin;
|
||||
width: calc(75% - #{$margin});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.debate-summary,
|
||||
.proposal-summary,
|
||||
.annotation-summary {
|
||||
@extend %panel;
|
||||
min-height: auto;
|
||||
padding-bottom: rem-calc(16);
|
||||
padding-top: rem-calc(16);
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: $line-height / 2;
|
||||
}
|
||||
}
|
||||
|
||||
.comments-count {
|
||||
@include has-fa-icon(comments, r);
|
||||
}
|
||||
|
||||
.question-title:not(:only-child) {
|
||||
margin-bottom: $line-height / 2;
|
||||
}
|
||||
|
||||
.annotation-title {
|
||||
margin-bottom: $line-height / 2;
|
||||
margin-top: $line-height / 2;
|
||||
}
|
||||
|
||||
.annotation-quote {
|
||||
border: 1px solid $black;
|
||||
padding: rem-calc(10);
|
||||
}
|
||||
|
||||
.comment-summary {
|
||||
margin-bottom: $line-height / 2;
|
||||
|
||||
> :first-child {
|
||||
background-color: rgba(217, 216, 243, 0.2);
|
||||
border-radius: rem-calc(10);
|
||||
padding: rem-calc(12);
|
||||
}
|
||||
}
|
||||
|
||||
.download-button {
|
||||
margin-bottom: 0;
|
||||
margin-left: 50%;
|
||||
margin-top: $line-height;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,3 +148,18 @@
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin has-fa-icon($icon, $style) {
|
||||
@extend .fa-#{$icon};
|
||||
|
||||
&::before {
|
||||
@extend %fa-icon;
|
||||
font-family: "Font Awesome 5 Free";
|
||||
|
||||
@if $style == "r" {
|
||||
font-weight: normal;
|
||||
} @else {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,15 +612,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
.debate,
|
||||
.proposal,
|
||||
.investment-project,
|
||||
.budget-investment,
|
||||
.legislation,
|
||||
.communities-show {
|
||||
margin: $line-height / 4 0;
|
||||
|
||||
.panel {
|
||||
%panel {
|
||||
background: #fff;
|
||||
border: 1px solid;
|
||||
border-color: #e5e6e9 #dfe0e4 #d0d1d5;
|
||||
@@ -659,6 +651,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
.debate,
|
||||
.proposal,
|
||||
.investment-project,
|
||||
.budget-investment,
|
||||
.legislation,
|
||||
.communities-show {
|
||||
margin: $line-height / 4 0;
|
||||
|
||||
.panel {
|
||||
@extend %panel;
|
||||
}
|
||||
|
||||
.debate-content,
|
||||
.proposal-content,
|
||||
.investment-project-content,
|
||||
|
||||
@@ -97,6 +97,17 @@ class Legislation::ProcessesController < Legislation::BaseController
|
||||
@phase = :milestones
|
||||
end
|
||||
|
||||
def summary
|
||||
@phase = :summary
|
||||
@proposals = @process.proposals.selected
|
||||
@comments = @process.draft_versions.published.last&.best_comments || Comment.none
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.xlsx { render xlsx: "summary", filename: "summary-#{Date.current}.xlsx" }
|
||||
end
|
||||
end
|
||||
|
||||
def proposals
|
||||
set_process
|
||||
@phase = :proposals_phase
|
||||
|
||||
@@ -90,7 +90,9 @@ module Abilities
|
||||
can :access, :ckeditor
|
||||
can :manage, Ckeditor::Picture
|
||||
|
||||
can [:manage], ::Legislation::Process
|
||||
can [:read, :debate, :draft_publication, :allegations, :result_publication,
|
||||
:milestones], Legislation::Process
|
||||
can [:create, :update, :destroy], Legislation::Process
|
||||
can [:manage], ::Legislation::DraftVersion
|
||||
can [:manage], ::Legislation::Question
|
||||
can [:manage], ::Legislation::Proposal
|
||||
|
||||
@@ -21,6 +21,8 @@ module Abilities
|
||||
can :new, DirectMessage
|
||||
can [:read, :debate, :draft_publication, :allegations, :result_publication,
|
||||
:proposals, :milestones], Legislation::Process, published: true
|
||||
can :summary, Legislation::Process,
|
||||
id: Legislation::Process.past.published.where(result_publication_enabled: true).ids
|
||||
can [:read, :changes, :go_to_version], Legislation::DraftVersion
|
||||
can [:read], Legislation::Question
|
||||
can [:read, :map, :share], Legislation::Proposal
|
||||
|
||||
@@ -49,6 +49,7 @@ class Comment < ApplicationRecord
|
||||
|
||||
scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) }
|
||||
scope :sort_descendants_by_most_voted, -> { order(confidence_score: :desc, created_at: :asc) }
|
||||
scope :sort_by_supports, -> { order("cached_votes_up - cached_votes_down DESC") }
|
||||
|
||||
scope :sort_by_newest, -> { order(created_at: :desc) }
|
||||
scope :sort_descendants_by_newest, -> { order(created_at: :desc) }
|
||||
@@ -129,6 +130,10 @@ class Comment < ApplicationRecord
|
||||
cached_votes_up)
|
||||
end
|
||||
|
||||
def votes_score
|
||||
cached_votes_up - cached_votes_down
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_body_length
|
||||
|
||||
@@ -40,4 +40,8 @@ class Legislation::DraftVersion < ApplicationRecord
|
||||
def total_comments
|
||||
annotations.sum(:comments_count)
|
||||
end
|
||||
|
||||
def best_comments
|
||||
Comment.where(commentable: annotations, ancestry: nil).sort_by_supports.limit(10)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -44,4 +44,8 @@ class Legislation::Question < ApplicationRecord
|
||||
def comments_open?
|
||||
process.debate_phase.open?
|
||||
end
|
||||
|
||||
def best_comments
|
||||
comments.sort_by_supports.limit(3)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<% if count > 0 %>
|
||||
<%= link_to "", class: "js-toggle-children relative" do %>
|
||||
<span class="far"></span>
|
||||
<%= link_to "", class: "js-toggle-children" do %>
|
||||
<span class="show-children"><%= t("comments.comment.responses_show", count: count) %></span>
|
||||
<span class="collapse-children"><%= t("comments.comment.responses_collapse", count: count) %></span>
|
||||
<% end %>
|
||||
|
||||
@@ -52,6 +52,15 @@
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
|
||||
<% if can?(:summary, process) %>
|
||||
<li <%= "class=is-active" if phase == :summary %>>
|
||||
<%= link_to summary_legislation_process_path(process) do %>
|
||||
<h4><%= t("legislation.summary.title") %></h4>
|
||||
<span><%= format_date(process.result_publication_date) %></span>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<section class="comments-phase">
|
||||
<header>
|
||||
<h3><%= t("legislation.summary.allegations_phase") %></h3>
|
||||
<h3><%= t("legislation.summary.top_comments", count: comments.count) %></h3>
|
||||
</header>
|
||||
|
||||
<% if comments.any? %>
|
||||
<div>
|
||||
<% comments.group_by(&:commentable).each do |annotation, annotation_comments| %>
|
||||
<div class="annotation-summary">
|
||||
<span><%= t("legislation.annotations.index.comments_about") %></span>
|
||||
<div class="annotation-title">
|
||||
<div class="annotation-quote">
|
||||
<%= annotation.quote %>
|
||||
</div>
|
||||
|
||||
<span class="comments-count">
|
||||
<%= link_to t("legislation.summary.comments", count: annotation.comments.count),
|
||||
polymorphic_path(annotation, anchor: "comments") %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<%= render "summary_comments", comments: annotation_comments %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="callout primary">
|
||||
<p><%= t("legislation.summary.no_allegation") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</section>
|
||||
10
app/views/legislation/processes/_summary_comments.html.erb
Normal file
10
app/views/legislation/processes/_summary_comments.html.erb
Normal file
@@ -0,0 +1,10 @@
|
||||
<% if comments.any? %>
|
||||
<span><%= t("legislation.summary.most_voted_comments") %></span>
|
||||
|
||||
<% comments.each do |comment| %>
|
||||
<div class="comment-summary">
|
||||
<%= link_to simple_format(sanitize(comment.body, tags: [])), comment_path(comment) %>
|
||||
<p><%= t("legislation.summary.votes", count: comment.votes_score) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
28
app/views/legislation/processes/_summary_debate.html.erb
Normal file
28
app/views/legislation/processes/_summary_debate.html.erb
Normal file
@@ -0,0 +1,28 @@
|
||||
<section class="debate-phase">
|
||||
<header>
|
||||
<h3><%= t("legislation.summary.debate_phase") %></h3>
|
||||
<h3><%= t("legislation.summary.debates", count: questions.count) %></h3>
|
||||
</header>
|
||||
|
||||
<% if questions.any? %>
|
||||
<div>
|
||||
<% questions.each do |question| %>
|
||||
<div class="debate-summary">
|
||||
<div class="question-title">
|
||||
<h4><%= link_to question.title, polymorphic_path(question) %></h4>
|
||||
<span class="comments-count">
|
||||
<%= link_to t("legislation.summary.comments", count: question.comments.count),
|
||||
polymorphic_path(question, anchor: "comments") %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<%= render "summary_comments", comments: question.best_comments %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="callout primary">
|
||||
<p><%= t("legislation.processes.debate.empty_questions") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</section>
|
||||
23
app/views/legislation/processes/_summary_proposals.html.erb
Normal file
23
app/views/legislation/processes/_summary_proposals.html.erb
Normal file
@@ -0,0 +1,23 @@
|
||||
<section class="proposals-phase">
|
||||
<header>
|
||||
<h3><%= t("legislation.summary.proposals_phase") %></h3>
|
||||
<h3><%= t("legislation.summary.proposals", count: proposals.count) %></h3>
|
||||
</header>
|
||||
|
||||
<% if proposals.any? %>
|
||||
<div>
|
||||
<% proposals.sort_by_supports.each do |proposal| %>
|
||||
<div class="proposal-summary">
|
||||
<h4>
|
||||
<%= link_to proposal.title, polymorphic_path(proposal) %>
|
||||
</h4>
|
||||
<p><%= t("legislation.summary.votes", count: proposal.votes_score) %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="callout primary">
|
||||
<p><%= t("legislation.processes.proposals.empty_proposals") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
</section>
|
||||
29
app/views/legislation/processes/summary.html.erb
Normal file
29
app/views/legislation/processes/summary.html.erb
Normal file
@@ -0,0 +1,29 @@
|
||||
<% provide(:title) { @process.title } %>
|
||||
|
||||
<%= render "legislation/processes/header", process: @process, header: :full %>
|
||||
|
||||
<%= render "key_dates", process: @process, phase: @phase %>
|
||||
|
||||
<% if @process.debate_phase.enabled? || @process.proposals_phase.enabled? || @process.allegations_phase.enabled? %>
|
||||
<section class="process-summary">
|
||||
<%= link_to t("legislation.summary.download"),
|
||||
summary_legislation_process_path(@process, format: :xlsx),
|
||||
class: "button hollow download-button" %>
|
||||
|
||||
<% if @process.debate_phase.enabled? %>
|
||||
<%= render "summary_debate", questions: @process.questions %>
|
||||
<% end %>
|
||||
|
||||
<% if @process.proposals_phase.enabled? %>
|
||||
<%= render "summary_proposals", proposals: @proposals %>
|
||||
<% end %>
|
||||
|
||||
<% if @process.allegations_phase.enabled? %>
|
||||
<%= render "summary_allegations", comments: @comments %>
|
||||
<% end %>
|
||||
</section>
|
||||
<% else %>
|
||||
<div class="callout primary">
|
||||
<p><%= t("legislation.summary.process_empty") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
50
app/views/legislation/processes/summary.xlsx.axlsx
Normal file
50
app/views/legislation/processes/summary.xlsx.axlsx
Normal file
@@ -0,0 +1,50 @@
|
||||
xlsx_package.workbook.add_worksheet(name: "Summary") do |sheet|
|
||||
|
||||
styles = xlsx_package.workbook.styles
|
||||
title = styles.add_style(b:true)
|
||||
link = styles.add_style(fg_color: "0000FF", u: true)
|
||||
|
||||
if @process.debate_phase.enabled? && @process.questions.any?
|
||||
sheet.add_row [t("legislation.summary.debate_phase"), t("legislation.summary.debates", count: @process.questions.count)], style: title
|
||||
@process.questions.each do |question|
|
||||
sheet.add_row [question.title, t("legislation.summary.comments", count: question.comments.count)], style: link
|
||||
sheet.add_hyperlink location: legislation_process_question_url(question.process, question), ref: sheet.rows.last.cells.first
|
||||
sheet.add_hyperlink location: polymorphic_url(question, anchor: "comments"), ref: sheet.rows.last.cells.last
|
||||
sheet.add_row [t("legislation.summary.most_voted_comments")] if question.best_comments.any?
|
||||
question.best_comments.each do |comment|
|
||||
sheet.add_row [comment.body, t("legislation.summary.votes", count: comment.votes_score)]
|
||||
sheet.add_hyperlink location: comment_url(comment), ref: sheet.rows.last.cells.first
|
||||
sheet.rows.last.cells.first.style = link
|
||||
end
|
||||
sheet.add_row ["", ""]
|
||||
end
|
||||
end
|
||||
|
||||
if @process.proposals_phase.enabled? && @proposals.any?
|
||||
sheet.add_row [t("legislation.summary.proposals_phase"), t("legislation.summary.proposals", count: @proposals.count)], style: title
|
||||
@proposals.sort_by_supports.each do |proposal|
|
||||
sheet.add_row [proposal.title, t("legislation.summary.votes", count: proposal.votes_score)]
|
||||
sheet.add_hyperlink location: legislation_process_proposal_url(proposal.legislation_process_id, proposal), ref: sheet.rows.last.cells.first
|
||||
sheet.rows.last.cells.first.style = link
|
||||
end
|
||||
sheet.add_row ["", ""]
|
||||
end
|
||||
|
||||
if @process.allegations_phase.enabled? && @comments.any?
|
||||
sheet.add_row [t("legislation.summary.allegations_phase"),
|
||||
t("legislation.summary.top_comments", count: @comments.count)], style: title
|
||||
@comments.group_by(&:commentable).each do |annotation, annotation_comments|
|
||||
sheet.add_row [t("legislation.annotations.index.comments_about")]
|
||||
sheet.add_row [annotation.quote, t("legislation.summary.comments", count: annotation.comments.count)]
|
||||
sheet.add_hyperlink location: polymorphic_url(annotation, anchor: "comments"), ref: sheet.rows.last.cells.last
|
||||
sheet.rows.last.cells.last.style = link
|
||||
|
||||
annotation_comments.each do |comment|
|
||||
sheet.add_row [comment.body, t("legislation.summary.votes", count: comment.votes_score)]
|
||||
sheet.add_hyperlink location: comment_url(comment), ref: sheet.rows.last.cells.first
|
||||
sheet.rows.last.cells.first.style = link
|
||||
end
|
||||
sheet.add_row ["", ""]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -118,3 +118,32 @@ en:
|
||||
tags_label: "Categories"
|
||||
not_verified: "For vote proposals %{verify_account}."
|
||||
process_title: Collaborative legislation process
|
||||
summary:
|
||||
title: "Summary"
|
||||
votes:
|
||||
zero: "%{count} votes"
|
||||
one: "%{count} vote"
|
||||
other: "%{count} votes"
|
||||
debate_phase: "Debate phase"
|
||||
proposals_phase: "Proposals phase"
|
||||
allegations_phase: "Comments phase"
|
||||
debates:
|
||||
zero: "No debates"
|
||||
one: "%{count} debate"
|
||||
other: "%{count} debates"
|
||||
proposals:
|
||||
zero: "No proposals"
|
||||
one: "%{count} proposal"
|
||||
other: "%{count} proposals"
|
||||
comments:
|
||||
zero: "No comments"
|
||||
one: "%{count} comment"
|
||||
other: "%{count} comments"
|
||||
download: "Download summary"
|
||||
top_comments:
|
||||
zero: "No comments"
|
||||
one: "%{count} comment"
|
||||
other: "Top comments"
|
||||
most_voted_comments: "Most voted comments"
|
||||
no_allegation: "There are no comments"
|
||||
process_empty: "This process didn't have any participation phases"
|
||||
|
||||
@@ -118,3 +118,32 @@ es:
|
||||
tags_label: "Categorías"
|
||||
not_verified: "Para votar propuestas %{verify_account}."
|
||||
process_title: Proceso de legislación colaborativa
|
||||
summary:
|
||||
title: "Resumen"
|
||||
votes:
|
||||
zero: "%{count} votos"
|
||||
one: "%{count} voto"
|
||||
other: "%{count} votos"
|
||||
debate_phase: "Fase de debate"
|
||||
proposals_phase: "Fase de propuestas"
|
||||
allegations_phase: "Fase de comentarios"
|
||||
debates:
|
||||
zero: "No hay debates"
|
||||
one: "%{count} debate"
|
||||
other: "%{count} debates"
|
||||
proposals:
|
||||
zero: "No hay propuestas"
|
||||
one: "%{count} propuesta"
|
||||
other: "%{count} propuestas"
|
||||
comments:
|
||||
zero: "No hay comentarios"
|
||||
one: "%{count} comentario"
|
||||
other: "%{count} comentarios"
|
||||
download: "Descargar resumen"
|
||||
top_comments:
|
||||
zero: "No hay comentarios"
|
||||
one: "%{count} comentario"
|
||||
other: "Los más votados"
|
||||
most_voted_comments: "Comentarios más votados"
|
||||
no_allegation: "No hay comentarios"
|
||||
process_empty: "Este proceso no ha tenido fases de participación"
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace :legislation do
|
||||
get :result_publication
|
||||
get :proposals
|
||||
get :milestones
|
||||
get :summary
|
||||
end
|
||||
|
||||
resources :questions, only: [:show] do
|
||||
|
||||
13
spec/controllers/legislation/processes_controller_spec.rb
Normal file
13
spec/controllers/legislation/processes_controller_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Legislation::ProcessesController do
|
||||
let(:legislation_process) { create(:legislation_process, end_date: Date.current - 1.day) }
|
||||
|
||||
it "download excel file test" do
|
||||
create(:legislation_question, process: legislation_process, title: "Question 1")
|
||||
|
||||
get :summary, params: { id: legislation_process, format: :xlsx }
|
||||
|
||||
expect(response).to be_success
|
||||
end
|
||||
end
|
||||
@@ -18,6 +18,10 @@ describe Abilities::Administrator do
|
||||
let(:legislation_question) { create(:legislation_question) }
|
||||
let(:poll_question) { create(:poll_question) }
|
||||
|
||||
let(:past_process) { create(:legislation_process, :past) }
|
||||
let(:past_draft_process) { create(:legislation_process, :past, :not_published) }
|
||||
let(:open_process) { create(:legislation_process, :open) }
|
||||
|
||||
let(:proposal_document) { build(:document, documentable: proposal, user: proposal.author) }
|
||||
let(:budget_investment_document) { build(:document, documentable: budget_investment) }
|
||||
let(:poll_question_document) { build(:document, documentable: poll_question) }
|
||||
@@ -67,6 +71,10 @@ describe Abilities::Administrator do
|
||||
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(:summary, past_process) }
|
||||
it { should_not be_able_to(:summary, past_draft_process) }
|
||||
it { should_not be_able_to(:summary, open_process) }
|
||||
|
||||
it { should be_able_to(:create, Budget) }
|
||||
it { should be_able_to(:update, Budget) }
|
||||
it { should be_able_to(:read_results, Budget) }
|
||||
|
||||
@@ -48,4 +48,8 @@ describe Abilities::Everyone do
|
||||
it { should be_able_to(:read_stats, create(:budget, :valuating, stats_enabled: true)) }
|
||||
it { should_not be_able_to(:read_stats, create(:budget, :valuating, stats_enabled: false)) }
|
||||
it { should_not be_able_to(:read_stats, create(:budget, :selecting, stats_enabled: true)) }
|
||||
|
||||
it { should be_able_to(:summary, create(:legislation_process, :past)) }
|
||||
it { should_not be_able_to(:summary, create(:legislation_process, :open)) }
|
||||
it { should_not be_able_to(:summary, create(:legislation_process, :past, :not_published)) }
|
||||
end
|
||||
|
||||
179
spec/system/legislation/summary_spec.rb
Normal file
179
spec/system/legislation/summary_spec.rb
Normal file
@@ -0,0 +1,179 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe "Legislation" do
|
||||
context "process summary page" do
|
||||
scenario "summary tab is not shown for open processes" do
|
||||
process = create(:legislation_process, :open)
|
||||
|
||||
visit legislation_process_path(process)
|
||||
|
||||
expect(page).not_to have_content "Summary"
|
||||
end
|
||||
|
||||
scenario "summary tab is shown por past processes" do
|
||||
process = create(:legislation_process, :past)
|
||||
|
||||
visit legislation_process_path(process)
|
||||
|
||||
expect(page).to have_content "Summary"
|
||||
end
|
||||
end
|
||||
|
||||
scenario "empty process" do
|
||||
process = create(:legislation_process, :empty,
|
||||
result_publication_enabled: true,
|
||||
end_date: Date.current - 1.day
|
||||
)
|
||||
|
||||
visit summary_legislation_process_path(process)
|
||||
|
||||
expect(page).to have_content "This process didn't have any participation phases"
|
||||
end
|
||||
|
||||
scenario "empty phases" do
|
||||
process = create(:legislation_process, end_date: Date.current - 1.day)
|
||||
visit summary_legislation_process_path(process)
|
||||
|
||||
expect(page).to have_content "Debate phase"
|
||||
expect(page).to have_content "No debates"
|
||||
expect(page).to have_content "There aren't any questions"
|
||||
|
||||
expect(page).to have_content "Proposals phase"
|
||||
expect(page).to have_content "No proposals"
|
||||
expect(page).to have_content "There are no proposals"
|
||||
|
||||
expect(page).to have_content "Comments phase"
|
||||
expect(page).to have_content "No comments"
|
||||
expect(page).to have_content "There are no comments"
|
||||
end
|
||||
|
||||
context "only debates exist" do
|
||||
let(:process) { create(:legislation_process, end_date: Date.current - 1.day) }
|
||||
let(:user) { create(:user, :level_two) }
|
||||
|
||||
before do
|
||||
create(:legislation_question, process: process, title: "Question 1") do |question|
|
||||
create(:comment, user: user, commentable: question, body: "Answer 1")
|
||||
create(:comment, user: user, commentable: question, body: "Answer 2")
|
||||
end
|
||||
|
||||
create(:legislation_question, process: process, title: "Question 2") do |question|
|
||||
create(:comment, user: user, commentable: question, body: "Answer 3")
|
||||
create(:comment, user: user, commentable: question, body: "Answer 4")
|
||||
end
|
||||
end
|
||||
|
||||
scenario "shows debates list" do
|
||||
visit summary_legislation_process_path(process)
|
||||
|
||||
expect(page).to have_content "Debate phase"
|
||||
expect(page).to have_content "2 debates"
|
||||
expect(page).to have_link "Question 1"
|
||||
expect(page).to have_content "Answer 1"
|
||||
expect(page).to have_content "Answer 2"
|
||||
expect(page).to have_link "Question 2"
|
||||
expect(page).to have_content "Answer 3"
|
||||
expect(page).to have_content "Answer 4"
|
||||
|
||||
expect(page).to have_content "Proposals phase"
|
||||
expect(page).to have_content "No proposals"
|
||||
expect(page).to have_content "There are no proposals"
|
||||
|
||||
expect(page).to have_content "Comments phase"
|
||||
expect(page).to have_content "No comments"
|
||||
expect(page).to have_content "There are no comments"
|
||||
end
|
||||
end
|
||||
|
||||
context "only proposals exist" do
|
||||
let(:process) { create(:legislation_process, end_date: Date.current - 1.day) }
|
||||
|
||||
before do
|
||||
create(:legislation_proposal, legislation_process_id: process.id,
|
||||
title: "Legislation proposal 1", selected: true)
|
||||
create(:legislation_proposal, legislation_process_id: process.id,
|
||||
title: "Legislation proposal 2", selected: false)
|
||||
create(:legislation_proposal, legislation_process_id: process.id,
|
||||
title: "Legislation proposal 3", selected: true)
|
||||
create(:legislation_proposal, legislation_process_id: process.id,
|
||||
title: "Legislation proposal 4", selected: false)
|
||||
end
|
||||
|
||||
scenario "shows proposals list" do
|
||||
visit summary_legislation_process_path(process)
|
||||
|
||||
expect(page).to have_content "Debate phase"
|
||||
expect(page).to have_content "No debates"
|
||||
expect(page).to have_content "There aren't any questions"
|
||||
|
||||
expect(page).to have_content "Proposals phase"
|
||||
expect(page).to have_content "2 proposals"
|
||||
expect(page).to have_link "Legislation proposal 1"
|
||||
expect(page).not_to have_content "Legislation proposal 2"
|
||||
expect(page).to have_link "Legislation proposal 3"
|
||||
expect(page).not_to have_content "Legislation proposal 4"
|
||||
|
||||
expect(page).to have_content "Comments phase"
|
||||
expect(page).to have_content "No comments"
|
||||
expect(page).to have_content "There are no comments"
|
||||
end
|
||||
end
|
||||
|
||||
context "only text comments exist" do
|
||||
let(:process) { create(:legislation_process, end_date: Date.current - 1.day) }
|
||||
|
||||
before do
|
||||
user = create(:user, :level_two)
|
||||
draft_version_1 = create(:legislation_draft_version, process: process,
|
||||
title: "Version 1", body: "Body of the first version",
|
||||
status: "published")
|
||||
draft_version_2 = create(:legislation_draft_version, process: process,
|
||||
title: "Version 2", body: "Body of the second version and that's it all of it",
|
||||
status: "published")
|
||||
annotation0 = create(:legislation_annotation,
|
||||
draft_version: draft_version_1, text: "my annotation123",
|
||||
ranges: annotation_ranges(5, 10))
|
||||
annotation1 = create(:legislation_annotation,
|
||||
draft_version: draft_version_2, text: "hola",
|
||||
ranges: annotation_ranges(5, 10))
|
||||
annotation2 = create(:legislation_annotation,
|
||||
draft_version: draft_version_2,
|
||||
ranges: annotation_ranges(12, 19))
|
||||
|
||||
create(:comment, user: user, commentable: annotation0, body: "Comment 0")
|
||||
create(:comment, user: user, commentable: annotation1, body: "Comment 1")
|
||||
create(:comment, user: user, commentable: annotation2, body: "Comment 2")
|
||||
create(:comment, user: user, commentable: annotation2, body: "Comment 3")
|
||||
end
|
||||
|
||||
scenario "shows coments list" do
|
||||
visit summary_legislation_process_path(process)
|
||||
|
||||
expect(page).to have_content "Debate phase"
|
||||
expect(page).to have_content "No debates"
|
||||
expect(page).to have_content "There aren't any questions"
|
||||
|
||||
expect(page).to have_content "Proposals phase"
|
||||
expect(page).to have_content "No proposals"
|
||||
expect(page).to have_content "There are no proposals"
|
||||
|
||||
expect(page).to have_content "Comments phase"
|
||||
expect(page).to have_content "Top comments"
|
||||
expect(page).not_to have_content "Comment 0"
|
||||
expect(page).to have_link "Comment 1"
|
||||
expect(page).to have_link "Comment 2"
|
||||
expect(page).to have_link "Comment 3"
|
||||
end
|
||||
|
||||
scenario "excel download" do
|
||||
visit summary_legislation_process_path(process)
|
||||
click_link "Download summary"
|
||||
|
||||
expect(page.response_headers["Content-Type"]).to match(/officedocument.spreadsheetml/)
|
||||
end
|
||||
end
|
||||
|
||||
def annotation_ranges(start_offset, end_offset)
|
||||
[{ "start" => "/p[1]", "startOffset" => start_offset, "end" => "/p[1]", "endOffset" => end_offset }]
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user