Merge branch 'legislation-module-stable' into 107-social-share-for-annotations

This commit is contained in:
Amaia Castro
2017-02-14 18:14:00 +01:00
25 changed files with 328 additions and 108 deletions

View File

@@ -52,6 +52,7 @@
//= require markdown-it //= require markdown-it
//= require markdown_editor //= require markdown_editor
//= require cocoon //= require cocoon
//= require legislation_admin
//= require legislation //= require legislation
//= require legislation_allegations //= require legislation_allegations
//= require legislation_annotatable //= require legislation_annotatable
@@ -83,6 +84,7 @@ var initialize_modules = function() {
App.Banners.initialize(); App.Banners.initialize();
App.SocialShare.initialize(); App.SocialShare.initialize();
App.MarkdownEditor.initialize(); App.MarkdownEditor.initialize();
App.LegislationAdmin.initialize();
App.LegislationAllegations.initialize(); App.LegislationAllegations.initialize();
App.Legislation.initialize(); App.Legislation.initialize();
if ( $(".legislation-annotatable").length ) if ( $(".legislation-annotatable").length )

View File

@@ -0,0 +1,14 @@
App.LegislationAdmin =
initialize: ->
$("input[type='checkbox'][data-disable-date]").on
change: ->
checkbox = $(this)
parent = $(this).parents('.row:eq(0)')
date_selector = $(this).data('disable-date')
parent.find("input[type='text'][id^='"+date_selector+"']").each ->
if checkbox.is(':checked')
$(this).removeAttr("disabled")
else
$(this).val("")

View File

@@ -56,7 +56,14 @@ App.LegislationAnnotatable =
return return
$('[data-annotation-id]').removeClass('current-annotation') $('[data-annotation-id]').removeClass('current-annotation')
$(this).addClass('current-annotation')
parent = $(this).parents('[data-annotation-id]:eq(0)')
if parent.length
target = parent
else
target = $(this)
annotation_id = target.data('annotation-id')
$('[data-annotation-id="'+annotation_id+'"]').addClass('current-annotation')
App.LegislationAllegations.show_comments() App.LegislationAllegations.show_comments()
$("#comments-box").show() $("#comments-box").show()

View File

@@ -8,8 +8,20 @@ class Legislation::ProcessesController < Legislation::BaseController
end end
def show def show
if @process.active_phase?(:allegations) && @process.show_phase?(:allegations) && draft_version = @process.draft_versions.published.last
redirect_to legislation_process_draft_version_path(@process, draft_version)
elsif @process.active_phase?(:debate)
redirect_to legislation_process_debate_path(@process)
else
redirect_to legislation_process_allegations_path(@process)
end
end
def debate
phase :debate
if @process.show_phase?(:debate) if @process.show_phase?(:debate)
render :show render :debate
else else
render :phase_not_open render :phase_not_open
end end

View File

@@ -16,7 +16,7 @@ module Abilities
can [:read], Budget::Group can [:read], Budget::Group
can [:read, :print], Budget::Investment can [:read, :print], Budget::Investment
can :new, DirectMessage can :new, DirectMessage
can [:read, :draft_publication, :allegations, :final_version_publication], Legislation::Process can [:read, :debate, :draft_publication, :allegations, :final_version_publication], Legislation::Process
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 [:create], Legislation::Answer can [:create], Legislation::Answer

View File

@@ -14,7 +14,7 @@ class Legislation::Annotation < ActiveRecord::Base
validates :draft_version, presence: true validates :draft_version, presence: true
validates :author, presence: true validates :author, presence: true
before_save :store_range before_save :store_range, :store_context
after_create :create_first_comment after_create :create_first_comment
def store_range def store_range
@@ -24,6 +24,26 @@ class Legislation::Annotation < ActiveRecord::Base
self.range_end_offset = ranges.first["endOffset"] self.range_end_offset = ranges.first["endOffset"]
end end
def store_context
begin
html = draft_version.body_html
doc = Nokogiri::HTML(html)
selector_start = "/html/body/#{range_start}"
el_start = doc.at_xpath(selector_start)
selector_end = "/html/body/#{range_end}"
el_end = doc.at_xpath(selector_end)
remainder_el_start = el_start.text[0 .. range_start_offset-1] unless range_start_offset.zero?
remainder_el_end = el_end.text[range_end_offset .. -1]
self.context = "#{remainder_el_start}<span class=annotator-hl>#{quote}</span>#{remainder_el_end}"
rescue
"<span class=annotator-hl>#{quote}</span>"
end
end
def create_first_comment def create_first_comment
comments.create(body: self.text, user: self.author) comments.create(body: self.text, user: self.author)
end end

View File

@@ -9,12 +9,10 @@ class Legislation::Process < ActiveRecord::Base
validates :title, presence: true validates :title, presence: true
validates :start_date, presence: true validates :start_date, presence: true
validates :end_date, presence: true validates :end_date, presence: true
validates :debate_start_date, presence: true validates :debate_start_date, presence: true, if: :debate_end_date?
validates :debate_end_date, presence: true validates :debate_end_date, presence: true, if: :debate_start_date?
validates :draft_publication_date, presence: true validates :allegations_start_date, presence: true, if: :allegations_end_date?
validates :allegations_start_date, presence: true validates :allegations_end_date, presence: true, if: :allegations_start_date?
validates :allegations_end_date, presence: true
validates :final_publication_date, presence: true
validate :valid_date_ranges validate :valid_date_ranges
scope :open, -> { where("start_date <= ? and end_date >= ?", Date.current, Date.current).order('id DESC') } scope :open, -> { where("start_date <= ? and end_date >= ?", Date.current, Date.current).order('id DESC') }
@@ -26,13 +24,13 @@ class Legislation::Process < ActiveRecord::Base
case phase case phase
when :debate when :debate
today >= debate_start_date && today <= debate_end_date active_phase?(:debate) && today >= debate_start_date && today <= debate_end_date
when :draft_publication when :draft_publication
today >= draft_publication_date active_phase?(:draft_publication) && today >= draft_publication_date
when :allegations when :allegations
today >= allegations_start_date && today <= allegations_end_date active_phase?(:allegations) && today >= allegations_start_date && today <= allegations_end_date
when :final_version_publication when :final_version_publication
today >= final_publication_date active_phase?(:final_version_publication) && today >= final_publication_date
end end
end end
@@ -42,13 +40,26 @@ class Legislation::Process < ActiveRecord::Base
case phase case phase
when :debate when :debate
today >= debate_start_date active_phase?(:debate) && today >= debate_start_date
when :draft_publication when :draft_publication
today >= draft_publication_date active_phase?(:draft_publication) && today >= draft_publication_date
when :allegations when :allegations
today >= allegations_start_date active_phase?(:allegations) && today >= allegations_start_date
when :final_version_publication when :final_version_publication
today >= final_publication_date active_phase?(:final_version_publication) && today >= final_publication_date
end
end
def active_phase?(phase)
case phase
when :debate
debate_start_date.present? && debate_end_date.present?
when :draft_publication
draft_publication_date.present?
when :allegations
allegations_start_date.present? && allegations_end_date.present?
when :final_version_publication
final_publication_date.present?
end end
end end

View File

@@ -63,6 +63,10 @@
class: "js-calendar-full", class: "js-calendar-full",
id: "debate_end_date" %> id: "debate_end_date" %>
</div> </div>
<div class="small-12 medium-2 column">
<%= check_box_tag :debate_phase_active, @process.active_phase?(:debate), @process.new_record? || @process.active_phase?(:debate), data: {disable_date: "debate"} %>
<%= label_tag :debate_phase_active, t('admin.legislation.processes.form.active') %>
</div>
<div class="small-12 medium-4 column"> <div class="small-12 medium-4 column">
<label><%= t('admin.legislation.processes.form.allegations_phase') %></label> <label><%= t('admin.legislation.processes.form.allegations_phase') %></label>
@@ -87,7 +91,13 @@
class: "js-calendar-full", class: "js-calendar-full",
id: "allegations_end_date" %> id: "allegations_end_date" %>
</div> </div>
<div class="small-12 medium-2 column">
<%= check_box_tag :allegations_phase_active, @process.active_phase?(:allegations), @process.new_record? || @process.active_phase?(:allegations), data: {disable_date: "allegations"} %>
<%= label_tag :allegations_phase_active, t('admin.legislation.processes.form.active') %>
</div>
</div>
<div class="row">
<div class="small-12 medium-4 column"> <div class="small-12 medium-4 column">
<%= f.label :draft_publication_date %> <%= f.label :draft_publication_date %>
</div> </div>
@@ -98,6 +108,10 @@
class: "js-calendar-full", class: "js-calendar-full",
id: "draft_publication_date" %> id: "draft_publication_date" %>
</div> </div>
<div class="small-12 medium-2 column">
<%= check_box_tag :draft_publication_phase_active, @process.active_phase?(:draft_publication), @process.new_record? || @process.active_phase?(:draft_publication), data: {disable_date: "draft_publication"} %>
<%= label_tag :draft_publication_phase_active, t('admin.legislation.processes.form.active') %>
</div>
</div> </div>
<div class="row"> <div class="row">
@@ -111,6 +125,10 @@
class: "js-calendar-full", class: "js-calendar-full",
id: "final_publication_date" %> id: "final_publication_date" %>
</div> </div>
<div class="small-12 medium-2 column">
<%= check_box_tag :final_version_publication_phase_active, @process.active_phase?(:final_version_publication), @process.new_record? || @process.active_phase?(:final_version_publication), data: {disable_date: "final_publication"} %>
<%= label_tag :final_version_publication_phase_active, t('admin.legislation.processes.form.active') %>
</div>
</div> </div>
<div class="row"> <div class="row">

View File

@@ -7,7 +7,7 @@
<div class="column row"> <div class="column row">
<div class="draft-panels small-12 column row"> <div class="draft-panels small-12 column row">
<%= render 'version_chooser', process: @process, draft_version: @draft_version %> <%= render 'version_chooser', process: @process, draft_version: @draft_version %>
<aside class="small-12 medium-3 column absolute"> <aside class="small-12 medium-3 column absolute">
<div class="sidebar-divider"></div> <div class="sidebar-divider"></div>
<h2>Compartir</h2> <h2>Compartir</h2>
@@ -16,9 +16,9 @@
</div> </div>
</aside> </aside>
</div> </div>
<div class="small-12 medium-8 column row legislation-comments end"> <div class="small-12 medium-8 column row legislation-comments end">
<% @annotations.each do |annotation| %> <% @annotations.each do |annotation| %>
<div class="comment"> <div class="comment">
<strong><%= t('.comments_about') %></strong> <strong><%= t('.comments_about') %></strong>
@@ -28,7 +28,7 @@
<% end %> <% end %>
</span> </span>
<div class="comment-section"> <div class="comment-section">
<%= annotation.quote %> <%= annotation.context.try(:html_safe).presence || annotation.quote %>
</div> </div>
<%= link_to legislation_process_draft_version_annotation_path(@process, @draft_version, annotation) do %> <%= link_to legislation_process_draft_version_annotation_path(@process, @draft_version, annotation) do %>
<span class="icon-comments" aria-hidden="true"></span> <span><%= t('.comments_count', count: annotation.comments_count) %></span></a> <span class="icon-comments" aria-hidden="true"></span> <span><%= t('.comments_count', count: annotation.comments_count) %></span></a>

View File

@@ -15,7 +15,7 @@
<div class="comment-section"> <div class="comment-section">
<div class="row"> <div class="row">
<div class="small-12 medium-10 column legislation-comment"> <div class="small-12 medium-10 column legislation-comment">
<%= @annotation.quote %> <%= @annotation.context.try(:html_safe).presence || @annotation.quote %>
</div> </div>
<div class="small-12 medium-2 column legislation-comment"> <div class="small-12 medium-2 column legislation-comment">
<span class="pull-right"> <span class="pull-right">

View File

@@ -1,32 +1,43 @@
<nav class="legislation-process-categories"> <nav class="legislation-process-categories">
<div class="legislation-process-list"> <div class="legislation-process-list">
<ul> <ul>
<%= render 'legislation/processes/key_dates_svg' %> <%= render 'legislation/processes/key_dates_svg' %>
<li <%= "class=active" if phase == :debate %>> <% if process.active_phase?(:debate) %>
<%= link_to process do %> <li <%= "class=active" if phase == :debate %>>
<h4><%= t('legislation.processes.shared.debate_dates') %></h4> <%= link_to legislation_process_debate_path(process) do %>
<p><%= format_date(process.debate_start_date) %> - <%= format_date(process.debate_end_date) %></p> <h4><%= t('legislation.processes.shared.debate_dates') %></h4>
<% end %> <p><%= format_date(process.debate_start_date) %> - <%= format_date(process.debate_end_date) %></p>
</li> <% end %>
<li <%= "class=active" if phase == :draft_publication %>> </li>
<%= link_to legislation_process_draft_publication_path(process) do %> <% end %>
<h4><%= t('legislation.processes.shared.draft_publication_date') %></h4>
<p><%= format_date(process.draft_publication_date) %></p> <% if process.active_phase?(:draft_publication) %>
<% end %> <li <%= "class=active" if phase == :draft_publication %>>
</li> <%= link_to legislation_process_draft_publication_path(process) do %>
<li <%= "class=active" if phase == :allegations %>> <h4><%= t('legislation.processes.shared.draft_publication_date') %></h4>
<%= link_to legislation_process_allegations_path(process) do %> <p><%= format_date(process.draft_publication_date) %></p>
<h4><%= t('legislation.processes.shared.allegations_dates') %></h4> <% end %>
<p><%= format_date(process.allegations_start_date) %> - <%= format_date(process.allegations_end_date) %></p> </li>
<% end %> <% end %>
</li>
<li <%= "class=active" if phase == :final_version_publication %>> <% if process.active_phase?(:allegations) %>
<%= link_to legislation_process_final_version_publication_path(process) do %> <li <%= "class=active" if phase == :allegations %>>
<h4><%= t('legislation.processes.shared.final_publication_date') %></h4> <%= link_to legislation_process_allegations_path(process) do %>
<p><%= format_date(process.final_publication_date) %></p> <h4><%= t('legislation.processes.shared.allegations_dates') %></h4>
<% end %> <p><%= format_date(process.allegations_start_date) %> - <%= format_date(process.allegations_end_date) %></p>
</li> <% end %>
</li>
<% end %>
<% if process.active_phase?(:final_version_publication) %>
<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>
<% end %>
</ul> </ul>
</div> </div>
</nav> </nav>

View File

@@ -0,0 +1,25 @@
<% provide :title do %><%= @process.title %><% end %>
<%= render 'legislation/processes/header', process: @process, header: :full %>
<%= render 'key_dates', process: @process, phase: :debate %>
<div class="row">
<div class="debate-chooser">
<div class="row">
<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>
</div>
</div>
</div>

View File

@@ -10,14 +10,9 @@
<div class="debate-draft"> <div class="debate-draft">
<div class="small-12 medium-7 column"> <div class="small-12 medium-7 column">
<h3><%= t('.not_open') %></h3> <h3><%= t('.not_open') %></h3>
<p>Suscríbete al proceso para recibir un aviso en el momento en que se abra.</p>
</div> </div>
<div class="small-12 medium-5 column"> <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>
</div> </div>
</div> </div>

View File

@@ -1,13 +0,0 @@
<% provide :title do %><%= @process.title %><% end %>
<%= render 'legislation/processes/header', process: @process, header: :full %>
<%= render 'key_dates', process: @process, phase: :debate %>
<div class="row">
<div class="debate-chooser">
<div class="row">
<%= render 'debate', process: @process %>
</div>
</div>
</div>

View File

@@ -193,6 +193,7 @@ en:
form: form:
error: Error error: Error
form: form:
active: Active
process: Process process: Process
debate_phase: Debate phase debate_phase: Debate phase
allegations_phase: Allegations phase allegations_phase: Allegations phase

View File

@@ -193,6 +193,7 @@ es:
form: form:
error: Error error: Error
form: form:
active: Activa
process: Proceso process: Proceso
debate_phase: Fase previa debate_phase: Fase previa
allegations_phase: Fase de alegaciones allegations_phase: Fase de alegaciones

View File

@@ -102,6 +102,7 @@ Rails.application.routes.draw do
namespace :legislation do namespace :legislation do
resources :processes, only: [:index, :show] do resources :processes, only: [:index, :show] do
get :debate
get :draft_publication get :draft_publication
get :allegations get :allegations
get :final_version_publication get :final_version_publication

View File

@@ -0,0 +1,5 @@
class AddContextForLegislationAnnotations < ActiveRecord::Migration
def change
add_column :legislation_annotations, :context, :text
end
end

View File

@@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170125093101) do ActiveRecord::Schema.define(version: 20170210083026) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@@ -339,6 +339,7 @@ ActiveRecord::Schema.define(version: 20170125093101) do
t.integer "range_start_offset" t.integer "range_start_offset"
t.string "range_end" t.string "range_end"
t.integer "range_end_offset" t.integer "range_end_offset"
t.text "context"
end end
add_index "legislation_annotations", ["author_id"], name: "index_legislation_annotations_on_author_id", using: :btree add_index "legislation_annotations", ["author_id"], name: "index_legislation_annotations_on_author_id", using: :btree

View File

@@ -16,8 +16,8 @@ describe Legislation::AnnotationsController do
post :create, process_id: @process.id, post :create, process_id: @process.id,
draft_version_id: @draft_version.id, draft_version_id: @draft_version.id,
legislation_annotation: { legislation_annotation: {
"quote"=>"Ordenación Territorial", "quote"=>"ipsum",
"ranges"=>[{"start"=>"/p[1]", "startOffset"=>1, "end"=>"/p[1]", "endOffset"=>3}], "ranges"=>[{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}],
"text": "una anotacion" "text": "una anotacion"
} }
expect(Ahoy::Event.where(name: :legislation_annotation_created).count).to eq 1 expect(Ahoy::Event.where(name: :legislation_annotation_created).count).to eq 1
@@ -30,8 +30,8 @@ describe Legislation::AnnotationsController do
post :create, process_id: @process.id, post :create, process_id: @process.id,
draft_version_id: @final_version.id, draft_version_id: @final_version.id,
legislation_annotation: { legislation_annotation: {
"quote"=>"Ordenación Territorial", "quote"=>"ipsum",
"ranges"=>[{"start"=>"/p[1]", "startOffset"=>1, "end"=>"/p[1]", "endOffset"=>3}], "ranges"=>[{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}],
"text": "una anotacion" "text": "una anotacion"
} }
@@ -45,8 +45,8 @@ describe Legislation::AnnotationsController do
xhr :post, :create, process_id: @process.id, xhr :post, :create, process_id: @process.id,
draft_version_id: @draft_version.id, draft_version_id: @draft_version.id,
legislation_annotation: { legislation_annotation: {
"quote"=>"Ordenación Territorial", "quote"=>"ipsum",
"ranges"=>[{"start"=>"/p[1]", "startOffset"=>1, "end"=>"/p[1]", "endOffset"=>3}], "ranges"=>[{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}],
"text": "una anotacion" "text": "una anotacion"
} }
end.to change { @draft_version.annotations.count }.by(1) end.to change { @draft_version.annotations.count }.by(1)
@@ -60,8 +60,8 @@ describe Legislation::AnnotationsController do
xhr :post, :create, process_id: @process.id, xhr :post, :create, process_id: @process.id,
draft_version_id: @draft_version.id, draft_version_id: @draft_version.id,
legislation_annotation: { legislation_annotation: {
"quote"=>"Ordenación Territorial", "quote"=>"ipsum",
"ranges"=>[{"start"=>"/p[1]", "startOffset"=>1, "end"=>"/p[1]", "endOffset"=>3}], "ranges"=>[{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}],
"text": "una anotacion" "text": "una anotacion"
} }
end.to_not change { @draft_version.annotations.count } end.to_not change { @draft_version.annotations.count }
@@ -74,8 +74,8 @@ describe Legislation::AnnotationsController do
xhr :post, :create, process_id: @process.id, xhr :post, :create, process_id: @process.id,
draft_version_id: @draft_version.id, draft_version_id: @draft_version.id,
legislation_annotation: { legislation_annotation: {
"quote"=>"Ordenación Territorial", "quote"=>"ipsum",
"ranges"=>[{"start"=>"/p[1]", "startOffset"=>1, "end"=>"/p[1]", "endOffset"=>3}].to_json, "ranges"=>[{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}].to_json,
"text": "una anotacion" "text": "una anotacion"
} }
end.to change { @draft_version.annotations.count }.by(1) end.to change { @draft_version.annotations.count }.by(1)
@@ -83,16 +83,16 @@ describe Legislation::AnnotationsController do
it 'should create a new comment on an existing annotation when range is the same' do it 'should create a new comment on an existing annotation when range is the same' do
annotation = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation", annotation = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation",
ranges: [{"start"=>"/p[1]", "startOffset"=>5, "end"=>"/p[1]", "endOffset"=>10}], ranges: [{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}],
range_start: "/p[1]", range_start_offset: 5, range_end: "/p[1]", range_end_offset: 10) range_start: "/p[1]", range_start_offset: 6, range_end: "/p[1]", range_end_offset: 11)
sign_in @user sign_in @user
expect do expect do
xhr :post, :create, process_id: @process.id, xhr :post, :create, process_id: @process.id,
draft_version_id: @draft_version.id, draft_version_id: @draft_version.id,
legislation_annotation: { legislation_annotation: {
"quote"=>"Ordenación Territorial", "quote"=>"ipsum",
"ranges"=>[{"start"=>"/p[1]", "startOffset"=>5, "end"=>"/p[1]", "endOffset"=>10}], "ranges"=>[{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}],
"text": "una anotacion" "text": "una anotacion"
} }
end.to_not change { @draft_version.annotations.count } end.to_not change { @draft_version.annotations.count }

View File

@@ -505,7 +505,19 @@ FactoryGirl.define do
changelog "What changed in this version" changelog "What changed in this version"
status "draft" status "draft"
final_version false final_version false
body "Body of the legislation text" body <<-LOREM_IPSUM
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Expetenda tincidunt in sed, ex partem placerat sea, porro commodo ex eam. His putant aeterno interesset at. Usu ea mundi tincidunt, omnium virtute aliquando ius ex. Ea aperiri sententiae duo. Usu nullam dolorum quaestio ei, sit vidit facilisis ea. Per ne impedit iracundia neglegentur. Consetetur neglegentur eum ut, vis animal legimus inimicus id.
His audiam deserunt in, eum ubique voluptatibus te. In reque dicta usu. Ne rebum dissentiet eam, vim omnis deseruisse id. Ullum deleniti vituperata at quo, insolens complectitur te eos, ea pri dico munere propriae. Vel ferri facilis ut, qui paulo ridens praesent ad. Possim alterum qui cu. Accusamus consulatu ius te, cu decore soleat appareat usu.
Est ei erat mucius quaeque. Ei his quas phaedrum, efficiantur mediocritatem ne sed, hinc oratio blandit ei sed. Blandit gloriatur eam et. Brute noluisse per et, verear disputando neglegentur at quo. Sea quem legere ei, unum soluta ne duo. Ludus complectitur quo te, ut vide autem homero pro.
Vis id minim dicant sensibus. Pri aliquip conclusionemque ad, ad malis evertitur torquatos his. Has ei solum harum reprimique, id illum saperet tractatos his. Ei omnis soleat antiopam quo. Ad augue inani postulant mel, mel ea qualisque forensibus.
Lorem salutandi eu mea, eam in soleat iriure assentior. Tamquam lobortis id qui. Ea sanctus democritum mei, per eu alterum electram adversarium. Ea vix probo dicta iuvaret, posse epicurei suavitate eam an, nam et vidit menandri. Ut his accusata petentium.
LOREM_IPSUM
trait :published do trait :published do
status "published" status "published"
@@ -520,12 +532,12 @@ FactoryGirl.define do
draft_version factory: :legislation_draft_version draft_version factory: :legislation_draft_version
author factory: :user author factory: :user
quote "ipsum" quote "ipsum"
text "Loremp ipsum dolor" text "a comment"
ranges [{"start"=>"/div[1]", "startOffset"=>5, "end"=>"/div[1]", "endOffset"=>10}] ranges [{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}]
range_start "/div[1]" range_start "/p[1]"
range_start_offset 5 range_start_offset 6
range_end "/div[1]" range_end "/p[1]"
range_end_offset 10 range_end_offset 11
end end
factory :legislation_question, class: 'Legislation::Question' do factory :legislation_question, class: 'Legislation::Question' do

View File

@@ -59,4 +59,27 @@ feature 'Admin legislation processes' do
expect(page).to have_content 'An example legislation process' expect(page).to have_content 'An example legislation process'
end end
end end
context 'Update' do
scenario 'Deactivate debate phase', js: true 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 "An example legislation process"
expect(page).to have_selector("h1", text: "An example legislation process")
expect(find("#debate_phase_active")).to be_checked
uncheck "debate_phase_active"
click_button "Save changes"
expect(page).to have_content "Process updated successfully"
expect(find("#debate_start_date").value).to be_blank
expect(find("#debate_end_date").value).to be_blank
end
end
end end

View File

@@ -137,7 +137,7 @@ feature 'Legislation Draft Versions' do
scenario 'Visit as anonymous' do scenario 'Visit as anonymous' do
logout logout
draft_version = create(:legislation_draft_version, :published, body: Faker::Lorem.paragraph) draft_version = create(:legislation_draft_version, :published)
visit legislation_process_draft_version_path(draft_version.process, draft_version) visit legislation_process_draft_version_path(draft_version.process, draft_version)
@@ -148,7 +148,7 @@ feature 'Legislation Draft Versions' do
end end
scenario 'Create' do scenario 'Create' do
draft_version = create(:legislation_draft_version, :published, body: Faker::Lorem.paragraph) draft_version = create(:legislation_draft_version, :published)
visit legislation_process_draft_version_path(draft_version.process, draft_version) visit legislation_process_draft_version_path(draft_version.process, draft_version)
@@ -172,7 +172,7 @@ feature 'Legislation Draft Versions' do
end end
scenario 'View annotations and comments' do scenario 'View annotations and comments' do
draft_version = create(:legislation_draft_version, :published, body: Faker::Lorem.paragraph) draft_version = create(:legislation_draft_version, :published)
annotation1 = create(:legislation_annotation, draft_version: draft_version, text: "my annotation", ranges: [{"start"=>"/p[1]", "startOffset"=>5, "end"=>"/p[1]", "endOffset"=>10}]) annotation1 = create(:legislation_annotation, draft_version: draft_version, text: "my annotation", ranges: [{"start"=>"/p[1]", "startOffset"=>5, "end"=>"/p[1]", "endOffset"=>10}])
annotation2 = create(:legislation_annotation, draft_version: draft_version, text: "my other annotation", ranges: [{"start"=>"/p[1]", "startOffset"=>12, "end"=>"/p[1]", "endOffset"=>19}]) annotation2 = create(:legislation_annotation, draft_version: draft_version, text: "my other annotation", ranges: [{"start"=>"/p[1]", "startOffset"=>12, "end"=>"/p[1]", "endOffset"=>19}])
@@ -187,8 +187,8 @@ feature 'Legislation Draft Versions' do
end end
scenario "Publish new comment for an annotation from comments box" do scenario "Publish new comment for an annotation from comments box" do
draft_version = create(:legislation_draft_version, :published, body: Faker::Lorem.paragraph) draft_version = create(:legislation_draft_version, :published)
annotation = create(:legislation_annotation, draft_version: draft_version, text: "my annotation", ranges: [{"start"=>"/p[1]", "startOffset"=>5, "end"=>"/p[1]", "endOffset"=>10}]) annotation = create(:legislation_annotation, draft_version: draft_version, text: "my annotation", ranges: [{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}])
visit legislation_process_draft_version_path(draft_version.process, draft_version) visit legislation_process_draft_version_path(draft_version.process, draft_version)
@@ -205,25 +205,25 @@ feature 'Legislation Draft Versions' do
context "Annotations page" do context "Annotations page" do
background do background do
@draft_version = create(:legislation_draft_version, :published, body: Faker::Lorem.paragraph) @draft_version = create(:legislation_draft_version, :published)
@annotation_1 = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation", quote: "first quote") @annotation_1 = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation", quote: "ipsum", ranges: [{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}])
@annotation_2 = create(:legislation_annotation, draft_version: @draft_version, text: "my other annotation", quote: "second quote") @annotation_2 = create(:legislation_annotation, draft_version: @draft_version, text: "my other annotation", quote: "audiam", ranges: [{"start"=>"/p[3]", "startOffset"=>6, "end"=>"/p[3]", "endOffset"=>11}])
end end
scenario "See all annotations for a draft version" do scenario "See all annotations for a draft version" do
visit legislation_process_draft_version_annotations_path(@draft_version.process, @draft_version) visit legislation_process_draft_version_annotations_path(@draft_version.process, @draft_version)
expect(page).to have_content "first quote" expect(page).to have_content "ipsum"
expect(page).to have_content "second quote" expect(page).to have_content "audiam"
end end
context "switching versions" do context "switching versions" do
background do background do
@process = create(:legislation_process) @process = create(:legislation_process)
@draft_version_1 = create(:legislation_draft_version, :published, process: @process, title: "Version 1", body: Faker::Lorem.paragraph) @draft_version_1 = create(:legislation_draft_version, :published, process: @process, title: "Version 1", body: "Text with quote for version 1")
@annotation_1 = create(:legislation_annotation, draft_version: @draft_version_1, text: "annotation for version 1", quote: "quote for version 1") @annotation_1 = create(:legislation_annotation, draft_version: @draft_version_1, text: "annotation for version 1", quote: "quote for version 1", ranges: [{"start"=>"/p[1]", "startOffset"=>11, "end"=>"/p[1]", "endOffset"=>30}])
@draft_version_2 = create(:legislation_draft_version, :published, process: @process, title: "Version 2", body: Faker::Lorem.paragraph) @draft_version_2 = create(:legislation_draft_version, :published, process: @process, title: "Version 2", body: "Text with quote for version 2")
@annotation_1 = create(:legislation_annotation, draft_version: @draft_version_2, text: "annotation for version 2", quote: "quote for version 2") @annotation_1 = create(:legislation_annotation, draft_version: @draft_version_2, text: "annotation for version 2", quote: "quote for version 2", ranges: [{"start"=>"/p[1]", "startOffset"=>11, "end"=>"/p[1]", "endOffset"=>30}])
end end
scenario "without js" do scenario "without js" do
@@ -251,17 +251,18 @@ feature 'Legislation Draft Versions' do
context "Annotation comments page" do context "Annotation comments page" do
background do background do
@draft_version = create(:legislation_draft_version, :published, body: Faker::Lorem.paragraph) @draft_version = create(:legislation_draft_version, :published)
@annotation_1 = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation", quote: "first quote") @annotation_1 = create(:legislation_annotation, draft_version: @draft_version, text: "my annotation", quote: "ipsum", ranges: [{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[1]", "endOffset"=>11}])
@annotation_2 = create(:legislation_annotation, draft_version: @draft_version, text: "my other annotation", quote: "second quote") @annotation_2 = create(:legislation_annotation, draft_version: @draft_version, text: "my other annotation", quote: "audiam", ranges: [{"start"=>"/p[3]", "startOffset"=>6, "end"=>"/p[3]", "endOffset"=>11}])
end end
scenario "See one annotation with replies for a draft version" do scenario "See one annotation with replies for a draft version" do
visit legislation_process_draft_version_annotation_path(@draft_version.process, @draft_version, @annotation_2) visit legislation_process_draft_version_annotation_path(@draft_version.process, @draft_version, @annotation_2)
expect(page).to_not have_content "first quote" expect(page).to_not have_content "ipsum"
expect(page).to have_content "second quote"
expect(page).to_not have_content "my annotation" expect(page).to_not have_content "my annotation"
expect(page).to have_content "audiam"
expect(page).to have_content "my other annotation" expect(page).to have_content "my other annotation"
end end
end end

View File

@@ -0,0 +1,47 @@
require 'rails_helper'
RSpec.describe Legislation::Annotation, type: :model do
let(:draft_version) { create(:legislation_draft_version) }
let(:annotation) { create(:legislation_annotation, draft_version: draft_version) }
it "should be valid" do
expect(draft_version).to be_valid
expect(annotation).to be_valid
end
it "calculates the context for multinode annotations" do
annotation = create(:legislation_annotation,
draft_version: draft_version,
quote: "ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Expetenda tincidunt in sed, ex partem placerat sea, porro commodo ex eam. His putant aeterno interesset at. Usu ea mundi tincidunt, omnium virtute aliquando ius ex. Ea aperiri sententiae duo. Usu nullam dolorum quaestio ei, sit vidit facilisis ea. Per ne impedit iracundia neglegentur. Consetetur neglegentur eum ut, vis animal legimus inimicus id.
His audiam",
ranges: [{"start"=>"/p[1]", "startOffset"=>6, "end"=>"/p[3]", "endOffset"=>11}]
)
expect(annotation.context).to eq("Lorem <span class=annotator-hl>ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nExpetenda tincidunt in sed, ex partem placerat sea, porro commodo ex eam. His putant aeterno interesset at. Usu ea mundi tincidunt, omnium virtute aliquando ius ex. Ea aperiri sententiae duo. Usu nullam dolorum quaestio ei, sit vidit facilisis ea. Per ne impedit iracundia neglegentur. Consetetur neglegentur eum ut, vis animal legimus inimicus id.\n\nHis audiam</span>deserunt in, eum ubique voluptatibus te. In reque dicta usu. Ne rebum dissentiet eam, vim omnis deseruisse id. Ullum deleniti vituperata at quo, insolens complectitur te eos, ea pri dico munere propriae. Vel ferri facilis ut, qui paulo ridens praesent ad. Possim alterum qui cu. Accusamus consulatu ius te, cu decore soleat appareat usu.")
end
it "calculates the context for multinode annotations 2" do
annotation = create(:legislation_annotation,
draft_version: draft_version,
quote: "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\r\n\r\nExpetenda tincidunt in sed, ex partem placerat sea, porro commodo ex eam. His putant aeterno interesset at. Usu ea mundi tincidunt, omnium virtute aliquando ius ex. Ea aperiri sententiae duo",
ranges: [{"start"=>"/p[1]", "startOffset"=>273, "end"=>"/p[2]", "endOffset"=>190}]
)
expect(annotation.context).to eq("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. <span class=annotator-hl>Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\r\n\r\nExpetenda tincidunt in sed, ex partem placerat sea, porro commodo ex eam. His putant aeterno interesset at. Usu ea mundi tincidunt, omnium virtute aliquando ius ex. Ea aperiri sententiae duo</span>. Usu nullam dolorum quaestio ei, sit vidit facilisis ea. Per ne impedit iracundia neglegentur. Consetetur neglegentur eum ut, vis animal legimus inimicus id.")
end
it "calculates the context for multinode annotations 3" do
draft_version = create(:legislation_draft_version, body: "The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software.\r\n\r\nThe licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.\r\n\r\nWhen we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.\r\n\r\nDevelopers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software.\r\n\r\nA secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public.\r\n\r\nThe GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version.\r\n\r\nAn older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license.")
annotation = create(:legislation_annotation,
draft_version: draft_version,
quote: "By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.\r\n\r\nWhen we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish)",
ranges: [{"start"=>"/p[2]", "startOffset"=>127, "end"=>"/p[3]", "endOffset"=>223}]
)
expect(annotation.context).to eq("The licenses for most software and other practical works are designed to take away your freedom to share and change the works. <span class=annotator-hl>By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.\r\n\r\nWhen we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish)</span>, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.")
end
end

View File

@@ -7,6 +7,32 @@ RSpec.describe Legislation::Process, type: :model do
expect(process).to be_valid expect(process).to be_valid
end end
describe "dates validations" do
it "is invalid if debate_start_date is present but debate_end_date is not" do
process = build(:legislation_process, debate_start_date: Date.current, debate_end_date: "")
expect(process).to be_invalid
expect(process.errors.messages[:debate_end_date]).to include("can't be blank")
end
it "is invalid if debate_end_date is present but debate_start_date is not" do
process = build(:legislation_process, debate_start_date: nil, debate_end_date: Date.current)
expect(process).to be_invalid
expect(process.errors.messages[:debate_start_date]).to include("can't be blank")
end
it "is invalid if allegations_start_date is present but debate_end_date is not" do
process = build(:legislation_process, allegations_start_date: Date.current, allegations_end_date: "")
expect(process).to be_invalid
expect(process.errors.messages[:allegations_end_date]).to include("can't be blank")
end
it "is invalid if debate_end_date is present but allegations_start_date is not" do
process = build(:legislation_process, allegations_start_date: nil, allegations_end_date: Date.current)
expect(process).to be_invalid
expect(process.errors.messages[:allegations_start_date]).to include("can't be blank")
end
end
describe "date ranges validations" do describe "date ranges validations" do
it "is invalid if end_date is before start_date" do it "is invalid if end_date is before start_date" do
process = build(:legislation_process, start_date: Date.current, end_date: Date.current - 1.day) process = build(:legislation_process, start_date: Date.current, end_date: Date.current - 1.day)