Merge pull request #4065 from consul/legislation_summary

Add collaborative legislation summary
This commit is contained in:
Javi Martín
2020-09-08 13:49:45 +02:00
committed by GitHub
27 changed files with 640 additions and 55 deletions

View File

@@ -10,6 +10,8 @@ gem "ancestry", "~> 3.0.7"
gem "audited", "~> 4.9.0" gem "audited", "~> 4.9.0"
gem "autoprefixer-rails", "~> 8.2.0" gem "autoprefixer-rails", "~> 8.2.0"
gem "cancancan", "~> 2.3.0" gem "cancancan", "~> 2.3.0"
gem "caxlsx", "~> 3.0.2"
gem "caxlsx_rails", "~> 0.6.2"
gem "ckeditor", "~> 4.3.0" gem "ckeditor", "~> 4.3.0"
gem "cocoon", "~> 1.2.14" gem "cocoon", "~> 1.2.14"
gem "daemons", "~> 1.3.1" gem "daemons", "~> 1.3.1"

View File

@@ -131,6 +131,14 @@ GEM
rack (>= 1.4) rack (>= 1.4)
rack-proxy (>= 0.6.0) rack-proxy (>= 0.6.0)
selenium-webdriver (~> 3.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) chef-utils (16.4.41)
childprocess (0.9.0) childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11) ffi (~> 1.0, >= 1.0.11)
@@ -638,6 +646,8 @@ DEPENDENCIES
capistrano3-puma (~> 4.0.0) capistrano3-puma (~> 4.0.0)
capybara (~> 3.29.0) capybara (~> 3.29.0)
capybara-webmock (~> 0.5.5) capybara-webmock (~> 0.5.5)
caxlsx (~> 3.0.2)
caxlsx_rails (~> 0.6.2)
ckeditor (~> 4.3.0) ckeditor (~> 4.3.0)
cocoon (~> 1.2.14) cocoon (~> 1.2.14)
coveralls (~> 0.8.22) coveralls (~> 0.8.22)

View File

@@ -2045,10 +2045,6 @@ table {
padding: $line-height / 4; padding: $line-height / 4;
position: relative; position: relative;
.relative {
padding-left: rem-calc(18);
}
.divider { .divider {
color: $text-light; color: $text-light;
display: inline-block; display: inline-block;
@@ -2060,23 +2056,22 @@ table {
} }
.responses-count { .responses-count {
.far {
@extend .fa-minus-square;
font-size: $small-font-size;
left: 0;
position: absolute;
text-decoration: none;
top: 2px;
}
.show-children { .show-children {
@include has-fa-icon(plus-square, r);
display: none; display: none;
} }
.collapse-children {
@include has-fa-icon(minus-square, r);
}
.show-children::before,
.collapse-children::before {
margin-right: rem-calc(6);
transform: translateY(1px);
}
&.collapsed { &.collapsed {
.far {
@extend .fa-plus-square;
}
.collapse-children { .collapse-children {
display: none; display: none;

View File

@@ -1006,3 +1006,91 @@
font-weight: bold; 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%);
}
}

View File

@@ -148,3 +148,18 @@
transition: none; 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;
}
}
}

View File

@@ -612,6 +612,45 @@
} }
} }
%panel {
background: #fff;
border: 1px solid;
border-color: #e5e6e9 #dfe0e4 #d0d1d5;
border-radius: 0;
box-shadow: 0 1px 3px 0 $border;
margin-bottom: rem-calc(12);
min-height: rem-calc(192);
padding: rem-calc(12) rem-calc(12) 0;
@include breakpoint(medium) {
margin-bottom: rem-calc(-1);
padding-bottom: rem-calc(12);
}
@include breakpoint(medium) {
.divider {
display: inline-block;
}
}
h3 {
font-weight: bold;
margin-top: $line-height / 2;
a {
color: $text;
}
}
&.past-budgets {
min-height: 0;
.button ~ .button {
margin-left: $line-height / 2;
}
}
}
.debate, .debate,
.proposal, .proposal,
.investment-project, .investment-project,
@@ -621,42 +660,7 @@
margin: $line-height / 4 0; margin: $line-height / 4 0;
.panel { .panel {
background: #fff; @extend %panel;
border: 1px solid;
border-color: #e5e6e9 #dfe0e4 #d0d1d5;
border-radius: 0;
box-shadow: 0 1px 3px 0 $border;
margin-bottom: rem-calc(12);
min-height: rem-calc(192);
padding: rem-calc(12) rem-calc(12) 0;
@include breakpoint(medium) {
margin-bottom: rem-calc(-1);
padding-bottom: rem-calc(12);
}
@include breakpoint(medium) {
.divider {
display: inline-block;
}
}
h3 {
font-weight: bold;
margin-top: $line-height / 2;
a {
color: $text;
}
}
&.past-budgets {
min-height: 0;
.button ~ .button {
margin-left: $line-height / 2;
}
}
} }
.debate-content, .debate-content,

View File

@@ -97,6 +97,17 @@ class Legislation::ProcessesController < Legislation::BaseController
@phase = :milestones @phase = :milestones
end 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 def proposals
set_process set_process
@phase = :proposals_phase @phase = :proposals_phase

View File

@@ -90,7 +90,9 @@ module Abilities
can :access, :ckeditor can :access, :ckeditor
can :manage, Ckeditor::Picture 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::DraftVersion
can [:manage], ::Legislation::Question can [:manage], ::Legislation::Question
can [:manage], ::Legislation::Proposal can [:manage], ::Legislation::Proposal

View File

@@ -21,6 +21,8 @@ module Abilities
can :new, DirectMessage can :new, DirectMessage
can [:read, :debate, :draft_publication, :allegations, :result_publication, can [:read, :debate, :draft_publication, :allegations, :result_publication,
:proposals, :milestones], Legislation::Process, published: true :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, :changes, :go_to_version], Legislation::DraftVersion
can [:read], Legislation::Question can [:read], Legislation::Question
can [:read, :map, :share], Legislation::Proposal can [:read, :map, :share], Legislation::Proposal

View File

@@ -49,6 +49,7 @@ class Comment < ApplicationRecord
scope :sort_by_most_voted, -> { order(confidence_score: :desc, created_at: :desc) } 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_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_by_newest, -> { order(created_at: :desc) }
scope :sort_descendants_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) cached_votes_up)
end end
def votes_score
cached_votes_up - cached_votes_down
end
private private
def validate_body_length def validate_body_length

View File

@@ -40,4 +40,8 @@ class Legislation::DraftVersion < ApplicationRecord
def total_comments def total_comments
annotations.sum(:comments_count) annotations.sum(:comments_count)
end end
def best_comments
Comment.where(commentable: annotations, ancestry: nil).sort_by_supports.limit(10)
end
end end

View File

@@ -44,4 +44,8 @@ class Legislation::Question < ApplicationRecord
def comments_open? def comments_open?
process.debate_phase.open? process.debate_phase.open?
end end
def best_comments
comments.sort_by_supports.limit(3)
end
end end

View File

@@ -1,6 +1,5 @@
<% if count > 0 %> <% if count > 0 %>
<%= link_to "", class: "js-toggle-children relative" do %> <%= link_to "", class: "js-toggle-children" do %>
<span class="far"></span>
<span class="show-children"><%= t("comments.comment.responses_show", count: count) %></span> <span class="show-children"><%= t("comments.comment.responses_show", count: count) %></span>
<span class="collapse-children"><%= t("comments.comment.responses_collapse", count: count) %></span> <span class="collapse-children"><%= t("comments.comment.responses_collapse", count: count) %></span>
<% end %> <% end %>

View File

@@ -52,6 +52,15 @@
<% end %> <% end %>
</li> </li>
<% end %> <% 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> </ul>
</div> </div>
</div> </div>

View File

@@ -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>

View 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 %>

View 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>

View 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>

View 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 %>

View 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

View File

@@ -118,3 +118,32 @@ en:
tags_label: "Categories" tags_label: "Categories"
not_verified: "For vote proposals %{verify_account}." not_verified: "For vote proposals %{verify_account}."
process_title: Collaborative legislation process 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"

View File

@@ -118,3 +118,32 @@ es:
tags_label: "Categorías" tags_label: "Categorías"
not_verified: "Para votar propuestas %{verify_account}." not_verified: "Para votar propuestas %{verify_account}."
process_title: Proceso de legislación colaborativa 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"

View File

@@ -7,6 +7,7 @@ namespace :legislation do
get :result_publication get :result_publication
get :proposals get :proposals
get :milestones get :milestones
get :summary
end end
resources :questions, only: [:show] do resources :questions, only: [:show] do

View 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

View File

@@ -18,6 +18,10 @@ describe Abilities::Administrator do
let(:legislation_question) { create(:legislation_question) } let(:legislation_question) { create(:legislation_question) }
let(:poll_question) { create(:poll_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(:proposal_document) { build(:document, documentable: proposal, user: proposal.author) }
let(:budget_investment_document) { build(:document, documentable: budget_investment) } let(:budget_investment_document) { build(:document, documentable: budget_investment) }
let(:poll_question_document) { build(:document, documentable: poll_question) } 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 be_able_to(:comment_as_administrator, legislation_question) }
it { should_not be_able_to(:comment_as_moderator, 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(:create, Budget) }
it { should be_able_to(:update, Budget) } it { should be_able_to(:update, Budget) }
it { should be_able_to(:read_results, Budget) } it { should be_able_to(:read_results, Budget) }

View File

@@ -48,4 +48,8 @@ describe Abilities::Everyone do
it { should be_able_to(:read_stats, create(:budget, :valuating, stats_enabled: true)) } 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, :valuating, stats_enabled: false)) }
it { should_not be_able_to(:read_stats, create(:budget, :selecting, stats_enabled: true)) } 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 end

View 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