diff options
-rw-r--r-- | site/app/controllers/voting_options_controller.rb | 16 | ||||
-rw-r--r-- | site/app/models/agenda.rb | 12 | ||||
-rw-r--r-- | site/app/models/vote.rb | 21 | ||||
-rw-r--r-- | site/app/models/voting_option.rb | 10 | ||||
-rw-r--r-- | site/app/views/taglibs/cards.dryml | 11 | ||||
-rw-r--r-- | site/config/routes.rb | 1 | ||||
-rw-r--r-- | site/features/step_definitions/voting_steps.rb | 34 | ||||
-rw-r--r-- | site/features/support/paths.rb | 2 | ||||
-rw-r--r-- | site/features/voting.feature | 13 |
9 files changed, 104 insertions, 16 deletions
diff --git a/site/app/controllers/voting_options_controller.rb b/site/app/controllers/voting_options_controller.rb index 951ddbb..14ec89f 100644 --- a/site/app/controllers/voting_options_controller.rb +++ b/site/app/controllers/voting_options_controller.rb @@ -3,4 +3,20 @@ class VotingOptionsController < ApplicationController hobo_model_controller auto_actions :all + + def community_vote + option = VotingOption.find(params[:id]) + unless option.nil? + if current_user.signed_up? + Vote.vote_for_option(current_user, option, false) + flash[:notice] = "You voted for #{option.description}" + else + flash[:notice] = "You must be logged in to vote" + end + redirect_to :controller => :agenda_items, :action => :show, :id => option.agenda_item_id + else + flash[:notice] = "No such voting option" + redirect_to :controller => :agendas, :action => :index + end + end end diff --git a/site/app/models/agenda.rb b/site/app/models/agenda.rb index ca40b57..1afed67 100644 --- a/site/app/models/agenda.rb +++ b/site/app/models/agenda.rb @@ -90,17 +90,7 @@ class Agenda < ActiveRecord::Base for voter in votes.keys option = VotingOption.first :conditions => { :agenda_item_id => item.id, :description => votes[voter] } user = ::User.find_by_irc_nick voter - old_vote = Vote.user_for_item(user.id, item.id).first - if old_vote.nil? - Vote.create! :voting_option => option, :user => user, :council_vote => true - else - # Result of Vote.user_for_item is read only so reload it - # Reload method won't work so use find. - old_vote = Vote.find(old_vote) - old_vote.voting_option = option - old_vote.council_vote = true - old_vote.save! - end + Vote.vote_for_option(user, option, true) end end end diff --git a/site/app/models/vote.rb b/site/app/models/vote.rb index c9695e9..9307cce 100644 --- a/site/app/models/vote.rb +++ b/site/app/models/vote.rb @@ -38,15 +38,28 @@ class Vote < ActiveRecord::Base false end - named_scope :user_for_item, lambda { |uid, iid| joins(:voting_option).where([ - 'voting_options.agenda_item_id = ? AND votes.user_id = ?', - iid, uid]) } + scope :for_item, lambda { |iid| joins(:voting_option).where([ + 'voting_options.agenda_item_id = ?', iid]) } + + def self.vote_for_option(user, option, council_vote) + item = option.agenda_item + old_vote = Vote.for_item(item.id).user_is(user.id).first + if old_vote.nil? + Vote.create! :voting_option => option, :user => user, :council_vote => council_vote + else + old_vote = Vote.find(old_vote) + old_vote.voting_option = option + old_vote.council_vote = council_vote + old_vote.save! + end + end + protected def user_voted_only_once return if user.nil? return if voting_option.nil? return if voting_option.agenda_item.nil? - other_votes = Vote.user_for_item(user_id, voting_option.agenda_item_id) + other_votes = Vote.for_item(voting_option.agenda_item_id).user_id_is(user_id) other_votes = other_votes.id_is_not(id) unless new_record? if other_votes.count > 0 errors.add(:user, 'User can vote only once per agenda item.') diff --git a/site/app/models/voting_option.rb b/site/app/models/voting_option.rb index b9c2226..9ece560 100644 --- a/site/app/models/voting_option.rb +++ b/site/app/models/voting_option.rb @@ -17,6 +17,16 @@ class VotingOption < ActiveRecord::Base description end + def community_votes + votes_for_this = votes.council_vote_is(false).count + votes_total = Vote.for_item(agenda_item.id).council_vote_is(false).count + + return "No community votes for this item yet." if votes_total.zero? + + votes_percentage = (100 * votes_for_this.to_f/votes_total).round + "#{votes_for_this} of #{votes_total} (#{votes_percentage}%) votes." + end + # --- Permissions --- # def create_permitted? diff --git a/site/app/views/taglibs/cards.dryml b/site/app/views/taglibs/cards.dryml index cb2a76d..7c2db42 100644 --- a/site/app/views/taglibs/cards.dryml +++ b/site/app/views/taglibs/cards.dryml @@ -6,3 +6,14 @@ </header:> </card> </def> + +<extend tag="card" for="VotingOption"> + <old-card merge> + <after-header:> + <body: param> + Community votes: <view:community_votes/> + <a href="&community_vote_path(this)" if="¤t_user.signed_up?">Vote for it</a> + </body:> + </after-header:> + </old-card> +</extend> diff --git a/site/config/routes.rb b/site/config/routes.rb index 0df79c8..dbecd4f 100644 --- a/site/config/routes.rb +++ b/site/config/routes.rb @@ -8,6 +8,7 @@ Council::Application.routes.draw do match 'agendas/current_items' => 'agendas#current_items', :as => 'current_items' match 'agendas/results' => 'agendas#results', :as => 'results' match 'agendas/reminders' => 'agendas#reminders', :as => 'reminders' + match 'voting_options/community_vote/:id' => 'voting_options#community_vote', :as => 'community_vote' # The priority is based upon order of creation: # first created -> highest priority. diff --git a/site/features/step_definitions/voting_steps.rb b/site/features/step_definitions/voting_steps.rb index 0519397..db6a5a0 100644 --- a/site/features/step_definitions/voting_steps.rb +++ b/site/features/step_definitions/voting_steps.rb @@ -20,3 +20,37 @@ When /^I go from the homepage to edit last voting option page$/ do When "I follow \"#{VotingOption.last.description}\"" When 'I follow "Edit Voting option"' end + +Given /^there is an item with some voting options for current agenda$/ do + agenda = Factory(:agenda) + item = Factory(:agenda_item, :agenda => agenda) + voting_option1 = Factory(:voting_option, :agenda_item => item) + voting_option2 = Factory(:voting_option, :agenda_item => item, :description => 'Another choice') +end + +Then /^I should see my vote$/ do + option = VotingOption.first + Then "I should see \"#{option.description}\"" + Then "I should see \"#{option.community_votes}\"" + Then "I should see \"You voted for #{option.description}\" in the notices" +end + +Given /^some community and council votes for a newer item$/ do + agenda = Agenda.current + item = Factory(:agenda_item, :agenda => agenda) + option1 = Factory(:voting_option, :agenda_item => item) + option2 = Factory(:voting_option, :agenda_item => item, :description => 'another option') + option3 = Factory(:voting_option, :agenda_item => item, :description => 'yet another option') + Factory(:vote, :voting_option => option1) + Factory(:vote, :voting_option => option2) + Factory(:vote, :voting_option => option2) + Factory(:vote, :voting_option => option3) + Factory(:vote, :voting_option => option3) + Factory(:vote, :voting_option => option3) +end + +Then /^I should see correct community votes$/ do + Then 'I should see "Community votes: 1 of 6 (17%) votes. "' + Then 'I should see "Community votes: 2 of 6 (33%) votes. "' + Then 'I should see "Community votes: 3 of 6 (50%) votes. "' +end diff --git a/site/features/support/paths.rb b/site/features/support/paths.rb index 0dc1576..e08acc5 100644 --- a/site/features/support/paths.rb +++ b/site/features/support/paths.rb @@ -36,7 +36,7 @@ module NavigationHelpers agenda_path(Agenda.find $1) when /newest agenda item page/ - agenda_item_path(AgendaItem.first) + agenda_item_path(AgendaItem.last) # Add more mappings here. # Here is an example that pulls values out of the Regexp: diff --git a/site/features/voting.feature b/site/features/voting.feature index 2e25318..febb16a 100644 --- a/site/features/voting.feature +++ b/site/features/voting.feature @@ -21,3 +21,16 @@ Feature: Application side of voting And I fill in "voting_option_description" with "some description" And I press "Save Voting option" Then I should see "some description" as voting option description + + Scenario: Vote as regular user + Given I am logged in as example user + And there is an item with some voting options for current agenda + When I am on the newest agenda item page + And I follow "Vote" + Then I should see my vote + + Scenario: View community vote results + Given there is an item with some voting options for current agenda + And some community and council votes for a newer item + When I am on the newest agenda item page + Then I should see correct community votes |