diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb
index 7aedd9c..eb52513 100644
--- a/app/controllers/proposals_controller.rb
+++ b/app/controllers/proposals_controller.rb
@@ -9,6 +9,7 @@ def index
@withdrawn_proposals = Proposal.withdrawn.all
@proposals = Proposal.active.order('created_at desc').all
+ @suggested_proposal = current_user.proposals_without_own_votes.active.sample || Proposal.active.sample if current_user
respond_with @proposals
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 22e9e49..092a74e 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -136,15 +136,18 @@ def authentication_links(container = :p)
['Facebook', '/auth/facebook']].map { |name, url| content_tag container, link_to(name, url) }.join("\n").html_safe
end
- def countdown_to_submissions_end
- submissions_end = Phase::ONE.ending_at
- if submissions_end > DateTime.now
- content_tag :span, '', id: 'counter', data: {countdown_end: submissions_end.to_i * 1000}
+ def countdown_to(phase_end)
+ if phase_end > DateTime.now
+ content_tag :span, '', id: 'counter', data: {countdown_end: phase_end.to_i * 1000}
else
content_tag :span, 'no time'
end
end
+ def countdown_to_phase_end
+ countdown_to current_phase.ending_at
+ end
+
protected
def markdown_parser(options = {})
@markdown_parser ||= Redcarpet::Markdown.new(Redcarpet::Render::HTML,
diff --git a/app/models/phase.rb b/app/models/phase.rb
index c107278..caefd8e 100644
--- a/app/models/phase.rb
+++ b/app/models/phase.rb
@@ -8,8 +8,19 @@ def self.all
[ZERO, ONE, INTERLUDE, TWO, CONFIRMATION, LINEUP]
end
+ def self.last_submission_date
+ ONE.ending_at
+ end
+
+ def self.last_voting_date
+ INTERLUDE.ending_at
+ end
+
attr_accessor :name
+ attr_accessor :main_text
+ attr_accessor :countdown_text
+
attr_accessor :starting_at
attr_accessor :ending_at
@@ -30,6 +41,8 @@ def self.all
ZERO = Phase.new.tap do |p|
p.name = "Before the beginning"
+ p.main_text = "Be part of #{Settings.event_name}: we highly encourage you to submit as many proposals as you want, help the authors make theirs better and finally select the most interesting ones for the final agenda! What are you waiting for?"
+ p.countdown_text = "before the submissions open!"
p.starting_at = DateTime.new(1970, 1, 1)
p.ending_at = DateTime.parse('2013-03-28T00:00:00+2')
@@ -42,6 +55,8 @@ def self.all
ONE = Phase.new.tap do |p|
p.name = "Phase 1: Submissions"
+ p.main_text = "Be part of #{Settings.event_name}: we highly encourage you to submit as many proposals as you want, help the authors make theirs better and finally select the most interesting ones for the final agenda! What are you waiting for?"
+ p.countdown_text = "to submit, refine and discuss proposals!"
p.starting_at = DateTime.parse('2013-03-28T00:00:00+2')
p.ending_at = DateTime.parse('2013-04-24T00:00:00+3')
@@ -54,6 +69,8 @@ def self.all
INTERLUDE = Phase.new.tap do |p|
p.name = "Interlude"
+ p.main_text = "Make it your #{Settings.event_name}: select the finalists before the grand voting! We highly encourage you to go through every single proposal select the most interesting ones. After all, this is what the conference is all about! What are you waiting for?"
+ p.countdown_text = "to cast your votes that will define the finalists!"
p.starting_at = DateTime.parse('2013-04-24T00:00:00+3')
p.ending_at = DateTime.parse('2013-04-29T00:00:00+3')
@@ -66,6 +83,8 @@ def self.all
TWO = Phase.new.tap do |p|
p.name = "Phase 2: Final voting"
+ p.main_text = "This is it! This is the time you define #{Settings.event_name}! Make your ideal lineup."
+ p.countdown_text = "to define the conference schedule!"
p.starting_at = DateTime.parse('2013-04-29T00:00:00+3')
p.ending_at = DateTime.parse('2013-05-06T00:00:00+3')
@@ -78,6 +97,7 @@ def self.all
CONFIRMATION = Phase.new.tap do |p|
p.name = "Speakers confirmation"
+ p.main_text = ""
p.starting_at = DateTime.parse('2013-05-06T00:00:00+3')
p.ending_at = DateTime.parse('2013-05-09T00:00:00+3')
@@ -90,6 +110,7 @@ def self.all
LINEUP = Phase.new.tap do |p|
p.name = "Lineup announcement"
+ p.main_text = ""
p.starting_at = DateTime.parse('2013-05-09T00:00:00+3')
p.ending_at = DateTime.parse('2100-01-01T00:00:00+2')
diff --git a/app/views/dashboard/index.html.erb b/app/views/dashboard/index.html.erb
index be81fd4..cb887a1 100644
--- a/app/views/dashboard/index.html.erb
+++ b/app/views/dashboard/index.html.erb
@@ -9,7 +9,7 @@
Your proposals
- You have still <%= countdown_to_submissions_end %> to submit or edit a proposal!
+ You have still <%= countdown_to Phase.last_submission_date %> to submit or edit a proposal!
Since proposals are anonymised, other users will not see that you are the author of these. <%= link_to "Read more about the process", about_path %>.
diff --git a/app/views/proposals/index.html.erb b/app/views/proposals/index.html.erb
index 5450913..e0b86b6 100644
--- a/app/views/proposals/index.html.erb
+++ b/app/views/proposals/index.html.erb
@@ -1,21 +1,21 @@
<%= page_title "#{Settings.event_name} Call for Presentations" %>
-
- Be part of <%= Settings.event_name %>:
- we highly encourage you to submit as many proposals as you want,
- help the authors make theirs better
- and finally select the most interesting ones for the final agenda!
- What are you waiting for?
-
+ <% if current_phase.main_text %>
+
<%= current_phase.main_text.html_safe %>
+ <% end %>
-
- You have <%= countdown_to_submissions_end %> to submit, refine and discuss proposals!
-
+ <% if current_phase.countdown_text %>
+
You have <%= countdown_to_phase_end %> <%= current_phase.countdown_text %>
+ <% end %>
<% if user_signed_in? %>
- <%= link_to "Propose a talk", new_proposal_path, :class => 'btn btn-primary' %>
+ <% if can? :create, Proposal %>
+ <%= link_to "Propose a talk", new_proposal_path, :class => 'btn btn-primary' %>
+ <% elsif @suggested_proposal && can?(:vote, @suggested_proposal) %>
+ <%= link_to "Cast your votes!", proposal_path(@suggested_proposal), :class => 'btn btn-primary' %>
+ <% end %>
<% else %>
<%= link_to 'Join the party', '#', :class => 'btn btn-primary dropdown-toggle', :data => {:toggle => 'dropdown'} %>
diff --git a/test/integration/proposal_test.rb b/test/integration/proposal_test.rb
index afcdd78..6e22f02 100644
--- a/test/integration/proposal_test.rb
+++ b/test/integration/proposal_test.rb
@@ -10,7 +10,12 @@ class ProposalTest < IntegrationTestCase
context "As a visitor to the site" do
should "not see a link to propose a talk" do
visit proposals_path
- assert !page.has_content?("Propose talk"), "link to propose talk should not be present!"
+ assert !page.has_content?("Propose a talk"), "link to propose talk should not be present!"
+ end
+
+ should "not see a link to vote for a talk" do
+ visit proposals_path
+ assert !page.has_content?("Cast your votes!"), "link to vote talks should not be present!"
end
should "not be able to propose a talk" do
@@ -67,6 +72,16 @@ class ProposalTest < IntegrationTestCase
sign_in @user
end
+ should "see a link to propose a talk" do
+ visit proposals_path
+ assert page.has_content?("Propose a talk"), "link to propose talk should be present!"
+ end
+
+ should "not see a link to vote for a talk" do
+ visit proposals_path
+ assert !page.has_content?("Cast your votes!"), "link to vote talks should not be present!"
+ end
+
context "and I propose a talk with all the required details" do
setup { propose_talk :title => "My Amazing Talk", :description => 'This talk is amazing.' }
@@ -220,6 +235,132 @@ class ProposalTest < IntegrationTestCase
end
end
+ [Phase::INTERLUDE].each do |phase|
+ context "During '#{phase.name}'" do
+ setup do
+ Phase.stubs(:current).returns(phase)
+ end
+
+ context "As a visitor to the site" do
+ should "not see a link to propose a talk" do
+ visit proposals_path
+ assert !page.has_content?("Propose a talk"), "link to propose talk should not be present!"
+ end
+
+ should "not see a link to vote for a talk" do
+ visit proposals_path
+ assert !page.has_content?("Cast your votes!"), "link to vote talks should not be present!"
+ end
+
+ should "not be able to propose a talk" do
+ visit new_proposal_path
+ i_am_asked_to_sign_in
+ end
+
+ context "given a proposal already exists" do
+ setup do
+ @proposal = FactoryGirl.create(:proposal, :title => "Ruby Muby Schmuby")
+ end
+
+ should "be able to see the list of proposals" do
+ visit proposals_path
+ assert page.has_css?('ul.proposals')
+ end
+
+ should "be able to subscribe to the rss feed of proposals" do
+ visit proposals_path
+ assert page.has_css?("link[rel='alternate'][type='application/rss+xml'][href$='#{proposals_path(:format => :rss)}']")
+ visit proposals_path(:format => :rss)
+ assert_match %r{application/rss\+xml}, page.response_headers['Content-Type']
+ assert page.has_xpath?('.//item/title', :text => @proposal.title)
+ end
+
+ should "be able to read individual proposals" do
+ visit proposals_path
+ click_link "Ruby Muby Schmuby"
+ assert_page_has_proposal :title => "Ruby Muby Schmuby"
+ end
+
+ should "not see a link to edit a proposal" do
+ visit proposals_path
+ click_link "Ruby Muby Schmuby"
+ assert !page.has_content?("Edit proposal"), "link to edit proposal should not be present"
+ end
+
+ should "not be able to edit a proposal" do
+ visit edit_proposal_path(@proposal)
+ i_am_asked_to_sign_in
+ end
+
+ should "my page view be tracked" do
+ assert_difference(lambda { @proposal.impressionist_count }, 1) do
+ visit proposal_path(@proposal)
+ end
+ end
+ end
+ end
+
+ context "Given I am logged in" do
+ setup do
+ @user = FactoryGirl.create(:user)
+ sign_in @user
+ end
+
+ should "not see a link to propose a talk" do
+ visit proposals_path
+ assert !page.has_content?("Propose a talk"), "link to propose talk should not be present!"
+ end
+
+ context "given a proposal already exists" do
+ setup do
+ @proposal = FactoryGirl.create(:proposal, :title => "Ruby Muby Schmuby")
+ end
+
+ should "see a link to vote for a talk" do
+ visit proposals_path
+ assert page.has_content?("Cast your votes!"), "link to vote talks should be present!"
+ end
+
+ should "be able to see the list of proposals" do
+ visit proposals_path
+ assert page.has_css?('ul.proposals')
+ end
+
+ should "be able to subscribe to the rss feed of proposals" do
+ visit proposals_path
+ assert page.has_css?("link[rel='alternate'][type='application/rss+xml'][href$='#{proposals_path(:format => :rss)}']")
+ visit proposals_path(:format => :rss)
+ assert_match %r{application/rss\+xml}, page.response_headers['Content-Type']
+ assert page.has_xpath?('.//item/title', :text => @proposal.title)
+ end
+
+ should "be able to read individual proposals" do
+ visit proposals_path
+ click_link "Ruby Muby Schmuby"
+ assert_page_has_proposal :title => "Ruby Muby Schmuby"
+ end
+
+ should "not see a link to edit a proposal" do
+ visit proposals_path
+ click_link "Ruby Muby Schmuby"
+ assert !page.has_content?("Edit proposal"), "link to edit proposal should not be present"
+ end
+
+ should "not be able to edit a proposal" do
+ visit edit_proposal_path(@proposal)
+ i_am_not_authorized
+ end
+
+ should "my page view be tracked" do
+ assert_difference(lambda { @proposal.impressionist_count }, 1) do
+ visit proposal_path(@proposal)
+ end
+ end
+ end
+ end
+ end
+ end
+
[Phase.all - [Phase::ONE, Phase::INTERLUDE]].flatten.each do |phase|
context "During '#{phase.name}'" do
setup do
@@ -229,7 +370,7 @@ class ProposalTest < IntegrationTestCase
context "As a visitor to the site" do
should "not see a link to propose a talk" do
visit proposals_path
- assert !page.has_content?("Propose talk"), "link to propose talk should not be present!"
+ assert !page.has_content?("Propose a talk"), "link to propose talk should not be present!"
end
should "not be able to propose a talk" do
@@ -288,7 +429,7 @@ class ProposalTest < IntegrationTestCase
should "not see a link to propose a talk" do
visit proposals_path
- assert !page.has_content?("Propose talk"), "link to propose talk should not be present!"
+ assert !page.has_content?("Propose a talk"), "link to propose talk should not be present!"
end
should "not be able to propose a talk" do