-
- <%= render 'votes',
- { proposal: @proposal, vote_url: vote_proposal_path(@proposal, value: 'yes') } %>
+ <% if @proposal.archived? %>
+
+ <%= t("proposals.proposal.supports", count: @proposal.total_votes) %>
+
+
<%= t("proposals.proposal.archived") %>
+ <% else %>
+
+
+ <%= render 'votes',
+ { proposal: @proposal, vote_url: vote_proposal_path(@proposal, value: 'yes') } %>
+
-
+ <% end %>
<%= t("proposals.show.share") %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 3a16722dc..61bf57c63 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -301,6 +301,7 @@ en:
hot_score: most active
most_commented: most commented
relevance: relevance
+ archival_date: Archived
retired_proposals: Retired proposals
retired_proposals_link: "Proposals retired by the author"
retired_links:
@@ -350,6 +351,7 @@ en:
zero: No supports
supports_necessary: "%{number} supports needed"
total_percent: 100%
+ archived: "This proposal has been archived and can't collect supports."
show:
author_deleted: User deleted
code: 'Proposal code:'
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 993ee8e95..04f844749 100755
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -301,6 +301,7 @@ es:
hot_score: Más activas hoy
most_commented: Más comentadas
relevance: Más relevantes
+ archival_date: Archivadas
retired_proposals: Propuestas retiradas
retired_proposals_link: "Propuestas retiradas por sus autores"
retired_links:
@@ -350,6 +351,7 @@ es:
zero: Sin apoyos
supports_necessary: "%{number} apoyos necesarios"
total_percent: 100%
+ archived: "Esta propuesta ha sido archivada y ya no puede recoger apoyos."
show:
author_deleted: Usuario eliminado
code: 'Código de la propuesta:'
diff --git a/config/locales/settings.en.yml b/config/locales/settings.en.yml
index 32874e32b..0035eb556 100755
--- a/config/locales/settings.en.yml
+++ b/config/locales/settings.en.yml
@@ -11,6 +11,7 @@ en:
max_votes_for_debate_edit: "Number of votes from which a Debate can no longer be edited"
proposal_code_prefix: "Prefix for Proposal codes"
votes_for_proposal_success: "Number of votes necessary for approval of a Proposal"
+ months_to_archive_proposals: "Months to archive Proposals"
email_domain_for_officials: "Email domain for public officials"
per_page_code: "Code to be included on every page"
feature:
diff --git a/config/locales/settings.es.yml b/config/locales/settings.es.yml
index aa5dea14e..1235762b4 100644
--- a/config/locales/settings.es.yml
+++ b/config/locales/settings.es.yml
@@ -11,6 +11,7 @@ es:
max_votes_for_debate_edit: "Número de votos en que un Debate deja de poderse editar"
proposal_code_prefix: "Prefijo para los códigos de Propuestas"
votes_for_proposal_success: "Número de votos necesarios para aprobar una Propuesta"
+ months_to_archive_proposals: "Meses para archivar las Propuestas"
email_domain_for_officials: "Dominio de email para cargos públicos"
per_page_code: "Código a incluir en cada página"
feature:
diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb
index 61b5f5060..3f47980eb 100644
--- a/db/dev_seeds.rb
+++ b/db/dev_seeds.rb
@@ -13,6 +13,7 @@ Setting.create(key: 'max_votes_for_debate_edit', value: '1000')
Setting.create(key: 'max_votes_for_proposal_edit', value: '1000')
Setting.create(key: 'proposal_code_prefix', value: 'MAD')
Setting.create(key: 'votes_for_proposal_success', value: '100')
+Setting.create(key: 'months_to_archive_proposals', value: '12')
Setting.create(key: 'comments_body_max_length', value: '1000')
Setting.create(key: 'twitter_handle', value: '@consul_dev')
diff --git a/db/seeds.rb b/db/seeds.rb
index 939a5f045..a5d8537db 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -31,6 +31,9 @@ Setting["proposal_code_prefix"] = 'MAD'
# Number of votes needed for proposal success
Setting["votes_for_proposal_success"] = 53726
+# Months to archive proposals
+Setting["months_to_archive_proposals"] = 12
+
# Users with this email domain will automatically be marked as level 1 officials
# Emails under the domain's subdomains will also be included
Setting["email_domain_for_officials"] = ''
diff --git a/spec/factories.rb b/spec/factories.rb
index cdcfe7381..13371a504 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -163,6 +163,10 @@ FactoryGirl.define do
end
end
+ trait :archived do
+ created_at 25.months.ago
+ end
+
trait :with_hot_score do
before(:save) { |d| d.calculate_hot_score }
end
diff --git a/spec/features/official_positions_spec.rb b/spec/features/official_positions_spec.rb
index 01f78370a..971a8fc6d 100644
--- a/spec/features/official_positions_spec.rb
+++ b/spec/features/official_positions_spec.rb
@@ -50,7 +50,7 @@ feature 'Official positions' do
@proposal1 = create(:proposal, author: @user1)
@proposal2 = create(:proposal, author: @user2)
- featured_proposals = 3.times { create(:proposal) }
+ create_featured_proposals
end
scenario "Index" do
diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb
index c7be4956b..9149531fd 100644
--- a/spec/features/proposals_spec.rb
+++ b/spec/features/proposals_spec.rb
@@ -3,48 +3,50 @@ require 'rails_helper'
feature 'Proposals' do
- scenario 'Index' do
- featured_proposals = create_featured_proposals
- proposals = [create(:proposal), create(:proposal), create(:proposal)]
+ context 'Index' do
+ scenario 'Lists featured and regular proposals' do
+ featured_proposals = create_featured_proposals
+ proposals = [create(:proposal), create(:proposal), create(:proposal)]
- visit proposals_path
+ visit proposals_path
- expect(page).to have_selector('#proposals .proposal-featured', count: 3)
- featured_proposals.each do |featured_proposal|
- within('#featured-proposals') do
- expect(page).to have_content featured_proposal.title
- expect(page).to have_css("a[href='#{proposal_path(featured_proposal)}']")
+ expect(page).to have_selector('#proposals .proposal-featured', count: 3)
+ featured_proposals.each do |featured_proposal|
+ within('#featured-proposals') do
+ expect(page).to have_content featured_proposal.title
+ expect(page).to have_css("a[href='#{proposal_path(featured_proposal)}']")
+ end
+ end
+
+ expect(page).to have_selector('#proposals .proposal', count: 3)
+ proposals.each do |proposal|
+ within('#proposals') do
+ expect(page).to have_content proposal.title
+ expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.title)
+ expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.summary)
+ end
end
end
- expect(page).to have_selector('#proposals .proposal', count: 3)
- proposals.each do |proposal|
- within('#proposals') do
- expect(page).to have_content proposal.title
- expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.title)
- expect(page).to have_css("a[href='#{proposal_path(proposal)}']", text: proposal.summary)
+ scenario 'Pagination' do
+ per_page = Kaminari.config.default_per_page
+ (per_page + 5).times { create(:proposal) }
+
+ visit proposals_path
+
+ expect(page).to have_selector('#proposals .proposal', count: per_page)
+
+ within("ul.pagination") do
+ expect(page).to have_content("1")
+ expect(page).to have_content("2")
+ expect(page).to_not have_content("3")
+ click_link "Next", exact: false
end
+
+ expect(page).to have_selector('#proposals .proposal', count: 2)
end
end
- scenario 'Paginated Index' do
- per_page = Kaminari.config.default_per_page
- (per_page + 5).times { create(:proposal) }
-
- visit proposals_path
-
- expect(page).to have_selector('#proposals .proposal', count: per_page)
-
- within("ul.pagination") do
- expect(page).to have_content("1")
- expect(page).to have_content("2")
- expect(page).to_not have_content("3")
- click_link "Next", exact: false
- end
-
- expect(page).to have_selector('#proposals .proposal', count: 2)
- end
-
scenario 'Show' do
proposal = create(:proposal)
@@ -676,6 +678,95 @@ feature 'Proposals' do
end
end
+ feature 'Archived proposals' do
+
+ scenario 'show on archived tab' do
+ create_featured_proposals
+ archived_proposals = create_archived_proposals
+
+ visit proposals_path
+ click_link 'Archived'
+
+ within("#proposals-list") do
+ archived_proposals.each do |proposal|
+ expect(page).to have_content(proposal.title)
+ end
+ end
+ end
+
+ scenario 'do not show in other index tabs' do
+ create_featured_proposals
+ archived_proposal = create(:proposal, :archived)
+
+ visit proposals_path
+
+ within("#proposals-list") do
+ expect(page).to_not have_content archived_proposal.title
+ end
+
+ orders = %w{hot_score confidence_score created_at relevance}
+ orders.each do |order|
+ visit proposals_path(order: order)
+
+ within("#proposals-list") do
+ expect(page).to_not have_content archived_proposal.title
+ end
+ end
+ end
+
+ scenario 'do not show support buttons in index' do
+ create_featured_proposals
+ archived_proposals = create_archived_proposals
+
+ visit proposals_path(order: 'archival_date')
+
+ within("#proposals-list") do
+ archived_proposals.each do |proposal|
+ within("#proposal_#{proposal.id}_votes") do
+ expect(page).to_not have_css(".supports")
+ expect(page).to have_content "This proposal has been archived and can't collect supports"
+ end
+ end
+ end
+ end
+
+ scenario 'do not show support buttons in show' do
+ archived_proposal = create(:proposal, :archived)
+
+ visit proposal_path(archived_proposal)
+ expect(page).to_not have_css(".supports")
+ expect(page).to have_content "This proposal has been archived and can't collect supports"
+ end
+
+ scenario 'do not show in featured proposals section' do
+ featured_proposal = create(:proposal, :with_confidence_score, cached_votes_up: 100)
+ archived_proposal = create(:proposal, :archived, :with_confidence_score, cached_votes_up: 10000)
+
+ visit proposals_path
+
+ within("#featured-proposals") do
+ expect(page).to have_content(featured_proposal.title)
+ expect(page).to_not have_content(archived_proposal.title)
+ end
+ within("#proposals-list") do
+ expect(page).to_not have_content(featured_proposal.title)
+ expect(page).to_not have_content(archived_proposal.title)
+ end
+
+ click_link "Archived"
+
+ within("#featured-proposals") do
+ expect(page).to have_content(featured_proposal.title)
+ expect(page).to_not have_content(archived_proposal.title)
+ end
+ within("#proposals-list") do
+ expect(page).to_not have_content(featured_proposal.title)
+ expect(page).to have_content(archived_proposal.title)
+ end
+ end
+
+ end
+
context "Search" do
context "Basic search" do
diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb
index 247cd9e66..d98392eaa 100644
--- a/spec/models/proposal_spec.rb
+++ b/spec/models/proposal_spec.rb
@@ -204,6 +204,13 @@ describe Proposal do
expect {proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(0)
end
end
+
+ it "should not register vote for archived proposals" do
+ user = create(:user, verified_at: Time.now)
+ archived_proposal = create(:proposal, :archived)
+
+ expect {archived_proposal.register_vote(user, 'yes')}.to change{proposal.reload.votes_for.size}.by(0)
+ end
end
describe '#cached_votes_up' do
@@ -811,4 +818,30 @@ describe Proposal do
end
end
+ describe "archived" do
+ before(:each) do
+ @new_proposal = create(:proposal)
+ @archived_proposal = create(:proposal, :archived)
+ end
+
+ it "archived? is true only for proposals created more than n (configured months) ago" do
+ expect(@new_proposal.archived?).to eq false
+ expect(@archived_proposal.archived?).to eq true
+ end
+
+ it "scope archived" do
+ archived = Proposal.archived
+
+ expect(archived.size).to eq(1)
+ expect(archived.first).to eq(@archived_proposal)
+ end
+
+ it "scope archived" do
+ not_archived = Proposal.not_archived
+
+ expect(not_archived.size).to eq(1)
+ expect(not_archived.first).to eq(@new_proposal)
+ end
+ end
+
end
diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb
index 60d6641bf..af57eb61c 100644
--- a/spec/support/common_actions.rb
+++ b/spec/support/common_actions.rb
@@ -192,6 +192,11 @@ module CommonActions
create(:debate, :with_confidence_score, cached_votes_up: 80)]
end
+ def create_archived_proposals
+ [create(:proposal, title: "This is an expired proposal", created_at: Setting["months_to_archive_proposals"].to_i.months.ago),
+ create(:proposal, title: "This is an oldest expired proposal", created_at: (Setting["months_to_archive_proposals"].to_i + 2).months.ago)]
+ end
+
def tag_names(tag_cloud)
tag_cloud.tags.map(&:name)
end