Created
November 11, 2010 02:44
-
-
Save zeroeth/671898 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ArrayExpander | |
attr_accessor :replacements | |
attr_accessor :column_order | |
def initialize | |
self.replacements = {} | |
end | |
### Process unquoted single items, or quoted evaluatable strings | |
def from_string(string) | |
if string.blank? | |
[] | |
elsif string.match(",") or string.match(":") | |
eval("[#{string}]") | |
else | |
[string] | |
end | |
end | |
### Wrap single items in an array for expander | |
def normalize(array) | |
return array if array.flatten.size < 2 | |
#return array unless array.any?{|element| element.kind_of?(Array)} | |
array.map do |element| | |
if element.kind_of?(Array) | |
element | |
else | |
[element] | |
end | |
end | |
end | |
def cell_expand(array) | |
return array if array.flatten.size < 2 | |
return array.first if array.size == 1 | |
expanded = [] | |
recursor( array, expanded) | |
expanded | |
end | |
### Iterate a 2D array, permuting the values of each sub array with one another. | |
def recursor(source, destination, in_stack = [], index = 0) | |
source[index].each do |element| | |
stack = in_stack.clone.push element | |
if source[index+1] | |
recursor source, destination, stack.clone, index+1 | |
else | |
destination.push stack | |
end | |
end | |
end | |
### Store replacement values | |
def set_replacement(key, value) | |
replacements[key] = value | |
end | |
### Substitute any stored values into the array | |
def replace_tokens(array) | |
array.map do |element| | |
replacements[element] || element | |
end | |
end | |
### what order to unwravel the arrays | |
def set_column_order(array) | |
self.column_order = array | |
end | |
def row_expand(hash) | |
expanded_rows = [] | |
pair_expander expanded_rows, hash, column_order, 0, Hash.new | |
expanded_rows | |
end | |
def add_to_destination(destination, output) | |
destination.push output.clone | |
end | |
# give it a hash like {:a => [1], :b => [2,3], :c => [:x,:y], and an iterator like [:a, [:b, c]] | |
# and you get back [{:a => 1, :b => 2, :c => :x}, {:a => 1, :b => 3, :c => :y}] | |
def pair_expander(destination, hash, iterators, index = 0, output = {}) | |
iterator = iterators[index] | |
# puts "|"*(2*index+1) + iterator.inspect | |
if iterator.kind_of? Array | |
hash[iterator.first].size.times do |sub_index| | |
iterator.each do |sub_iterator| | |
output[sub_iterator] = hash[sub_iterator][sub_index] | |
end | |
if iterators[index+1] | |
pair_expander(destination, hash, iterators, index+1, output.clone) | |
else | |
add_to_destination destination, output | |
end | |
end | |
else | |
if hash[iterator].empty? | |
output[iterator] = nil | |
if iterators[index+1] | |
pair_expander(destination, hash, iterators, index+1, output.clone) | |
else | |
add_to_destination destination, output | |
end | |
else | |
hash[iterator].each do |value| | |
output[iterator] = value | |
if iterators[index+1] | |
pair_expander(destination, hash, iterators, index+1, output.clone) | |
else | |
add_to_destination destination, output | |
end | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.dirname(__FILE__) + '/../test_helper' | |
class ArrayExpanderTest < ActiveSupport::TestCase | |
context "Expander" do | |
setup do | |
@expander = ArrayExpander.new | |
end | |
# IN "A, B, [C,D]" => OUT [A, B, [C, D]] | |
should "return array from string" do | |
array = @expander.from_string %{"A", "B", ["C", :D]} | |
assert_equal ["A", "B", ["C", :D]], array | |
array = @expander.from_string %{"A", "B", "C"} | |
assert_equal ["A", "B", "C"], array | |
array = @expander.from_string %{"1011", :all_programs} | |
assert_equal ["1011", :all_programs], array | |
end | |
should "return single items" do | |
array = @expander.from_string %{Some Name} | |
assert_equal ["Some Name"], array | |
end | |
should "return single items with commas" do | |
array = @expander.from_string %{"Some, Name"} | |
assert_equal ["Some, Name"], array | |
end | |
# IN "A, B, ["C,C",D]" => OUT [A, B, ["C, C", D]] | |
should "return from string with separator in name" do | |
array = @expander.from_string %{"A", "B", ["C, C", "D"]} | |
assert_equal ["A", "B", ["C, C", "D"]], array | |
end | |
# :all_regions.. register handler to return stuff (from outside world) | |
should "replace tokens" do | |
@expander.set_replacement :all_programs, ['P1', 'P2'] | |
array = @expander.replace_tokens [:all_programs, :A, :B] | |
assert_equal [['P1','P2'], :A, :B], array | |
end | |
# IN [A, B, [C, D]] => OUT [[A],[B],[C,D]] | |
should "wrap single first level items in arrays" do | |
array = @expander.normalize [:A, :B, [:C, :D]] | |
assert_equal [[:A], [:B], [:C,:D]], array | |
end | |
should "not wrap if no sub arrays" do | |
array = @expander.normalize [:A, :B, :C] | |
assert_equal [[:A], [:B], [:C]], array | |
array = @expander.normalize [[:A, :B, :C]] | |
assert_equal [[:A,:B,:C]], array | |
end | |
# IN [[A],[B],[C,D]] => OUT [[A,B,C],[A,B,D]] | |
should "expand cell array" do | |
array = @expander.cell_expand [[:A,:B], [:Q], [:Y, :Z]] | |
assert_equal [[:A, :Q, :Y], [:A, :Q, :Z], [:B, :Q, :Y], [:B, :Q, :Z]], array | |
end | |
should "expand single array" do | |
array = @expander.cell_expand [[:A,:B,:C]] | |
assert_equal [:A,:B,:C], array | |
end | |
should "build hash from csv row" | |
should "expand row hash" do | |
@expander.set_column_order [:other, :one, :empty, :two, :three, [:four, :five]] | |
source_row = {:other => ['other'], :one => [:a,:b], :empty => [], :two => [1], :three => [:q], :four => [:x,:y,:z], :five => [:X, :Y]} | |
rows = @expander.row_expand source_row | |
expected_rows = [{:other => 'other', :one => :a, :empty => nil, :two => 1, :three => :q, :four => :x, :five => :X}, | |
{:other => 'other', :one => :a, :empty => nil, :two => 1, :three => :q, :four => :y, :five => :Y}, | |
{:other => 'other', :one => :a, :empty => nil, :two => 1, :three => :q, :four => :z, :five => nil}, | |
{:other => 'other', :one => :b, :empty => nil, :two => 1, :three => :q, :four => :x, :five => :X}, | |
{:other => 'other', :one => :b, :empty => nil, :two => 1, :three => :q, :four => :y, :five => :Y}, | |
{:other => 'other', :one => :b, :empty => nil, :two => 1, :three => :q, :four => :z, :five => nil} | |
] | |
assert_equal 6, expected_rows.size | |
assert_equal expected_rows, rows | |
end | |
should "expand from inline order" | |
should "expand evaluation row" do | |
non_expanding_fields = ['Survey ID', 'Survey Name', 'Deployment Type', 'Supervisor', 'Take'] | |
expanding_fields = ['Shared Supervisor And Eval', 'Supervisor Group', 'Shared Eval', 'Evaluators', 'Evaluatees', ['Start On', 'End On', 'Deployment Name']] | |
@expander.set_column_order non_expanding_fields + expanding_fields | |
row ={ "Supervisor Group"=>["Assistant/Associate Directors"], | |
"Shared Eval"=>[], | |
"Survey ID"=>["1497"], | |
"Survey Name"=>["Faculty Evaluation"], | |
"Deployment Type"=>["Evaluation"], | |
"Supervisor"=>[], | |
"Take"=>[], | |
"Shared Supervisor And Eval"=>[["1011", "AZ"], ["1011", "BR"]],# ["1011", "PR"]], | |
"Evaluators"=>["Resident"], | |
"Evaluatees"=>["Faculty"], | |
"Deployment Name"=>[["First", "Trimester"], ["Second", "Trimester"], ["Third", "Trimester"]], | |
"End On"=>["2011-03-01", "2011-06-01", "2011-07-15"], | |
"Start On"=>["2010-11-01", "2011-03-01", "2011-06-01"] | |
} | |
rows = @expander.row_expand row | |
assert_equal 6, rows.size | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class InvalidEvaluatee < RuntimeError; end | |
class InvalidSigner < RuntimeError; end | |
class InvalidCloser < RuntimeError; end | |
class InvalidCompleter < RuntimeError; end | |
class AlreadySignedOff < RuntimeError; end | |
class EvaluationPortfolio < ActiveRecord::Base | |
belongs_to :evaluation | |
has_one :survey, :through => :evaluation | |
belongs_to :evaluation_deployment | |
has_one :evaluator_group, :through => :evaluation | |
has_one :evaluatee_group, :through => :evaluation | |
has_one :supervisor, :through => :evaluation | |
belongs_to :evaluatee, :class_name => 'User' | |
has_many :evaluation_survey_responses, :dependent => :destroy | |
has_many :comments, :as => :commentable, :dependent => :destroy | |
delegate :name, :to => :evaluation, :prefix => true | |
def evaluatee_name | |
evaluatee.name(:formal) | |
end | |
def review? | |
evaluation.discussion? | |
end | |
### ASSOCIATIONS ######################################## | |
# FIXME: wish this could be a has_many | |
def evaluators | |
evaluation_deployment.group.users | |
end | |
# FIXME: wish this could be a has_many | |
def responded_evaluators | |
evaluation_survey_responses.map(&:user) | |
end | |
def pending_evaluators | |
evaluators - responded_evaluators - [evaluatee] | |
end | |
### STATE MACHINE ####################################### | |
state_machine :state, :initial => :responding do | |
# NOTE put state based permission checks like.. can comment? for user and supervisor? | |
# if common patterns evolve out of the controllers | |
state :responding | |
state :reviewing | |
state :commenting | |
state :signing | |
state :complete | |
on :end_responding do | |
transition :responding => :complete, :if => :no_pending_and_review_false? | |
transition :responding => :reviewing, :if => :no_pending_and_review_true? | |
end | |
on :supervisor_force_end_responding do | |
transition :responding => :complete, :unless => :review? | |
transition :responding => :reviewing, :if => :review? | |
end | |
on :start_commenting do | |
transition :reviewing => :commenting, :if => :supervisor_commented? | |
end | |
on :sign_advance do | |
transition :signing => :complete, :if => :both_signed? | |
transition :commenting => :complete, :if => :both_signed? | |
transition :commenting => :signing, :if => :one_signed? | |
end | |
before_transition :update_state_timestamp | |
after_transition :to => :reviewing, :do => :reviewing_notification | |
after_transition :to => :commenting, :do => :commenting_notification | |
after_transition :to => :signing, :do => :signing_notification | |
after_transition :to => :complete, :do => :complete_notification | |
# TODO email/comment transition events here! | |
end | |
## TRANSITION GUARDS #################################### | |
def no_pending_and_review_true? | |
review? && pending_evaluators.empty? | |
end | |
def no_pending_and_review_false? | |
!review? && pending_evaluators.empty? | |
end | |
def supervisor_commented? | |
comments.any?{|comment| comment.user && is_supervisor?(comment.user) } | |
end | |
def none_signed? | |
!supervisor_signed? && !evaluatee_signed? | |
end | |
def one_signed? | |
supervisor_signed? ^ evaluatee_signed? | |
end | |
def both_signed? | |
supervisor_signed? && evaluatee_signed? | |
end | |
def supervisor_signed? | |
!supervisor_signed_at.nil? | |
end | |
def evaluatee_signed? | |
!evaluatee_signed_at.nil? | |
end | |
## TRANSITION EVENTS #################################### | |
def update_state_timestamp | |
self.state_started_at = Time.now | |
end | |
def reviewing_notification | |
comment "Supervisor is reviewing Evaluation." | |
Notifier.deliver_portfolio_start_reviewing self | |
end | |
def commenting_notification | |
comment "Open for Comments." | |
Notifier.deliver_portfolio_start_commenting self | |
end | |
def signing_notification | |
comment "Awaiting signature from #{needed_signatures}." | |
Notifier.deliver_portfolio_start_signing self | |
end | |
def complete_notification | |
comment "Evaluation for #{evaluatee.name(:proper)} is complete." | |
Notifier.deliver_portfolio_complete self | |
end | |
## METHODS ############################################## | |
# TODO this and the controllers could benefit from a single authorization matrix | |
# that echos the person being superuser/eval admin/supervisor/evaluatee based on state | |
# Only supervisors and evaluatee's can sign off. | |
def sign_off( person ) | |
if is_supervisor?(person) | |
raise AlreadySignedOff if supervisor_signed? | |
self.supervisor_signed_at = Time.now | |
comments.create! :from_system => true, :body => "Supervisor #{person.name(:formal)} signed off." | |
return self.supervisor_signed_at | |
elsif person.is?(evaluatee) | |
raise AlreadySignedOff if evaluatee_signed? | |
self.evaluatee_signed_at = Time.now | |
comments.create! :from_system => true, :body => "Evaluatee #{person.name(:formal)} signed off." | |
return self.evaluatee_signed_at | |
else | |
raise InvalidSigner | |
end | |
end | |
def needed_signatures | |
needed = [] | |
needed << "Evaluatee" unless evaluatee_signed? | |
needed << "Supervisor" unless supervisor_signed? | |
needed.join ' and ' | |
end | |
def name | |
"#{evaluation.name} #{evaluation_deployment.name} of #{evaluatee.name}" | |
end | |
def comment(body) | |
comments.create! :from_system => true, :skip_email => true, :body => body | |
end | |
### USER HELPERS ######################################## | |
def is_supervisor?(person) | |
person.is?(supervisor) || person.in_group?(EVALUATIONS_ADMIN_GROUP_NAME) | |
end | |
def supervisors | |
[supervisor, survey.account.evaluation_admins].flatten | |
end | |
def evaluatee_and_supervisors | |
[evaluatee, supervisors].flatten | |
end | |
def comment_recipients | |
evaluatee_and_supervisors | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require File.dirname(__FILE__) + '/../test_helper' | |
class EvaluationPortfolioTest < ActiveSupport::TestCase | |
fixtures :all | |
preload_factory_data :evaluations, :users, :evaluation_portfolios | |
should_belong_to :evaluation | |
should_belong_to :evaluatee | |
should_have_many :evaluation_survey_responses | |
should_have_many :comments | |
should_have_one :evaluator_group | |
should_have_one :evaluatee_group | |
should_belong_to :evaluation_deployment | |
should_have_one :supervisor | |
context "Portfolio" do | |
setup do | |
@portfolio = preload :evaluation_portfolio | |
@evaluation = @portfolio.evaluation | |
@supervisor = @portfolio.supervisor | |
admin_a = preload_next :user | |
admin_b = preload_next :user | |
Account.any_instance.stubs(:evaluation_admins).returns([admin_a, admin_b]) | |
@evaluation_admins = @evaluation.survey.account.evaluation_admins | |
should_receive_emails | |
end | |
should "start in responding state" do | |
assert_equal 'responding', @portfolio.state | |
end | |
should "update timestamp on state advance" do | |
assert_nil @portfolio.state_started_at | |
future = Time.now + 3.days | |
Delorean.time_travel_to future | |
@portfolio.supervisor_force_end_responding | |
assert_equal future.to_date, @portfolio.state_started_at.to_date | |
@portfolio = EvaluationPortfolio.find @portfolio | |
assert_equal future.to_date, @portfolio.state_started_at.to_date | |
end | |
should "force to review" do | |
@evaluation.update_attribute :discussion, true | |
@portfolio.reload | |
assert @portfolio.supervisor_force_end_responding | |
assert_equal 'reviewing', @portfolio.state | |
end | |
should "force to complete" do | |
@evaluation.update_attribute :discussion, false | |
@portfolio.reload | |
assert @portfolio.supervisor_force_end_responding | |
assert_equal 'complete', @portfolio.state | |
end | |
should "move to reviewing if no pending" do | |
@evaluation.update_attribute :discussion, true | |
@portfolio.reload | |
assert [email protected]_evaluators.empty? | |
assert [email protected]_end_responding? | |
@portfolio.pending_evaluators.each{|evaluator| EvaluationSurveyResponse.factory(:portfolio => @portfolio, :user => evaluator) } | |
@portfolio.reload | |
assert @portfolio.pending_evaluators.empty? | |
assert @portfolio.end_responding | |
assert_equal 'reviewing', @portfolio.state | |
end | |
should "move to complete if no pending" do | |
@evaluation.update_attribute :discussion, false | |
@portfolio.reload | |
assert [email protected]_evaluators.empty? | |
assert [email protected]_end_responding? | |
@portfolio.pending_evaluators.each{|evaluator| EvaluationSurveyResponse.factory(:portfolio => @portfolio, :user => evaluator) } | |
@portfolio.reload | |
assert @portfolio.end_responding | |
assert_equal 'complete', @portfolio.state | |
end | |
should "start commenting if one supervisor comment" do | |
@portfolio.update_attribute :state, 'reviewing' | |
assert @portfolio.comments.empty? | |
assert [email protected]_start_commenting? | |
# comment by user | |
Factory :comment, :user => @portfolio.evaluatee, :commentable => @portfolio | |
@portfolio.reload | |
assert [email protected]_start_commenting? | |
# comment by system | |
Factory :comment, :from_system => true, :commentable => @portfolio | |
@portfolio.reload | |
assert [email protected]_start_commenting? | |
# comment by supervisor | |
Factory :comment, :user => @portfolio.supervisor, :commentable => @portfolio | |
@portfolio.reload | |
assert @portfolio.start_commenting | |
assert_equal 'commenting', @portfolio.state | |
end | |
should "move from commenting to sign if supervisor sign" do | |
@portfolio.update_attribute :state, 'commenting' | |
assert [email protected]_signed? | |
assert [email protected]_sign_advance? | |
@portfolio.update_attribute :supervisor_signed_at, Time.now | |
assert @portfolio.supervisor_signed? | |
assert @portfolio.sign_advance | |
assert_equal 'signing', @portfolio.state | |
end | |
should "move from commenting to sign if evaluatee sign" do | |
@portfolio.update_attribute :state, 'commenting' | |
assert [email protected]_signed? | |
assert [email protected]_sign_advance? | |
@portfolio.update_attribute :evaluatee_signed_at, Time.now | |
assert @portfolio.evaluatee_signed? | |
assert @portfolio.sign_advance | |
assert_equal 'signing', @portfolio.state | |
end | |
should "move from commenting to complete if both signatures" do | |
@portfolio.update_attribute :state, 'commenting' | |
assert [email protected]_signed? | |
assert [email protected]_signed? | |
assert [email protected]_sign_advance? | |
@portfolio.update_attribute :evaluatee_signed_at, Time.now | |
@portfolio.update_attribute :supervisor_signed_at, Time.now | |
assert @portfolio.supervisor_signed? | |
assert @portfolio.evaluatee_signed? | |
assert @portfolio.sign_advance | |
assert_equal 'complete', @portfolio.state | |
end | |
should "not move from signing to complete if just supervisor signature" do | |
@portfolio.update_attribute :state, 'signing' | |
@portfolio.update_attribute :supervisor_signed_at, Time.now | |
assert @portfolio.supervisor_signed? | |
assert [email protected]_signed? | |
assert [email protected]_sign_advance? | |
end | |
should "not move from signing to complete if just evaluatee signature" do | |
@portfolio.update_attribute :state, 'signing' | |
@portfolio.update_attribute :evaluatee_signed_at, Time.now | |
assert [email protected]_signed? | |
assert @portfolio.evaluatee_signed? | |
assert [email protected]_sign_advance? | |
end | |
should "move from signing to complete if both signatures" do | |
@portfolio.update_attribute :state, 'signing' | |
@portfolio.update_attribute :evaluatee_signed_at, Time.now | |
assert [email protected]_signed? | |
assert @portfolio.evaluatee_signed? | |
assert [email protected]_sign_advance? | |
@portfolio.update_attribute :supervisor_signed_at, Time.now | |
assert @portfolio.supervisor_signed? | |
assert @portfolio.evaluatee_signed? | |
assert @portfolio.sign_advance | |
assert_equal 'complete', @portfolio.state | |
end | |
context "Notification Email and Comment" do | |
teardown do | |
assert_from @portfolio.evaluation.account.notifier_email | |
assert_match @portfolio.evaluation.account.host, last_email.body | |
assert_two_part_email | |
end | |
should "send on review start" do | |
@portfolio.state = 'responding' | |
@portfolio.stubs(:no_pending_and_review_false?).returns(false) | |
@portfolio.stubs(:no_pending_and_review_true? ).returns(true) | |
assert_delivers_email do | |
assert_creates_comment do | |
assert @portfolio.end_responding | |
end | |
end | |
assert_bcc_to @portfolio.supervisors | |
end | |
should "send on commenting start" do | |
@portfolio.state = 'reviewing' | |
@portfolio.stubs(:supervisor_commented?).returns(true) | |
assert_delivers_email do | |
assert_creates_comment do | |
assert @portfolio.start_commenting | |
end | |
end | |
assert_bcc_to @portfolio.evaluatee_and_supervisors | |
end | |
should "send on signing start" do | |
@portfolio.state = 'commenting' | |
@portfolio.stubs(:both_signed?).returns(false) | |
@portfolio.stubs(:one_signed? ).returns(true) | |
assert_delivers_email do | |
assert_creates_comment do | |
assert @portfolio.sign_advance | |
end | |
end | |
assert_bcc_to @portfolio.evaluatee_and_supervisors | |
assert_match @portfolio.needed_signatures, last_email.body | |
end | |
should "send on complete" do | |
@portfolio.state = 'signing' | |
@portfolio.stubs(:both_signed?).returns(true) | |
assert_delivers_email do | |
assert_creates_comment do | |
assert @portfolio.sign_advance | |
end | |
end | |
assert_bcc_to @portfolio.evaluatee_and_supervisors | |
end | |
end | |
end | |
context "Sign Off" do | |
setup do | |
@portfolio = preload :evaluation_portfolio | |
end | |
should "set sign date for supervisor" do | |
assert_nil @portfolio.supervisor_signed_at | |
now = Date.today | |
Delorean.jump 3.days | |
assert_difference 'Comment.count' do | |
@portfolio.sign_off @portfolio.supervisor | |
end | |
assert_equal (now + 3.days), @portfolio.supervisor_signed_at.to_date | |
assert_nil @portfolio.evaluatee_signed_at | |
end | |
should "set sign date for admin" do | |
@evaluation_admin = preload :user | |
@evaluation_admin.expects(:in_group?).with(EVALUATIONS_ADMIN_GROUP_NAME).returns(true) | |
now = Date.today | |
Delorean.jump 3.days | |
assert_nil @portfolio.supervisor_signed_at | |
assert_difference 'Comment.count' do | |
@portfolio.sign_off @evaluation_admin | |
end | |
assert_equal (now + 3.days), @portfolio.supervisor_signed_at.to_date | |
assert_nil @portfolio.evaluatee_signed_at | |
end | |
should "set sign date for evaluatee" do | |
assert_nil @portfolio.evaluatee_signed_at | |
now = Date.today | |
Delorean.jump 3.days | |
assert_difference 'Comment.count' do | |
@portfolio.sign_off @portfolio.evaluatee | |
end | |
assert_equal (now + 3.days), @portfolio.evaluatee_signed_at.to_date | |
assert_nil @portfolio.supervisor_signed_at | |
end | |
should "not sign if not authorized" do | |
other_user = preload :user | |
assert_raise InvalidSigner do | |
@portfolio.sign_off other_user | |
end | |
assert_nil @portfolio.evaluatee_signed_at | |
assert_nil @portfolio.supervisor_signed_at | |
end | |
end | |
context "pending evaluators" do | |
setup do | |
@portfolio = preload :evaluation_portfolio | |
@evaluatee = @portfolio.evaluatee | |
@evaluators = 3.times.collect{ preload_next :user } | |
@portfolio.evaluation_deployment.group.users = @evaluators | |
end | |
should "list all with no responses" do | |
assert_equal @evaluators, @portfolio.pending_evaluators | |
end | |
should "list all minus self if same group" do | |
@portfolio.evaluation_deployment.group.users << @evaluatee | |
assert_equal @evaluators, @portfolio.pending_evaluators | |
end | |
should "list all minus responses" do | |
@response = SurveyResponse.create! :survey_deployment => @portfolio.evaluation_deployment, :survey => @portfolio.survey, :user => @evaluators.first, :evaluatee => @evaluatee | |
@portfolio.reload | |
assert_equal (@evaluators - [@evaluators.first]).map(&:id).sort, @portfolio.pending_evaluators.map(&:id).sort | |
end | |
end | |
should "return comment recipients" do | |
@portfolio = preload :evaluation_portfolio | |
should_receive_emails | |
user_a = preload_next :user | |
user_b = preload_next :user | |
Account.any_instance.stubs(:evaluation_admins).returns([user_a, user_b]) | |
assert_equal [@portfolio.evaluatee, @portfolio.supervisor, user_a, user_b], @portfolio.comment_recipients | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment