diff --git a/spec/models/rate_spec.rb b/spec/models/rate_spec.rb deleted file mode 100644 index d068ca9..0000000 --- a/spec/models/rate_spec.rb +++ /dev/null @@ -1,298 +0,0 @@ -require File.dirname(__FILE__) + '/../spec_helper' - -module RateSpecHelper - def rate_valid_attributes - { - :user => mock_model(User), - :project => mock_model(Project), - :date_in_effect => Date.new(Date.today.year, 1, 1), - :amount => 100.50 - } - end -end - -describe Rate do - include RateSpecHelper - - it 'should be valid with a user' do - rate = Rate.new(rate_valid_attributes) - rate.should be_valid - end - - it 'should be valid with a project' do - rate = Rate.new(rate_valid_attributes) - rate.should be_valid - end - - it 'should be valid without a project' do - rate = Rate.new(rate_valid_attributes.except(:project)) - rate.should be_valid - end - - it 'should not be valid without a user' do - rate = Rate.new(rate_valid_attributes.except(:user)) - rate.should_not be_valid - rate.should have(1).error_on(:user_id) - end - - it 'should not be valid without a date_in_effect' do - rate = Rate.new(rate_valid_attributes.except(:date_in_effect)) - rate.should_not be_valid - rate.should have(1).error_on(:date_in_effect) - end -end - -describe Rate, 'associations' do - it 'should have many time entries' do - Rate.should have_association(:time_entries, :has_many) - end - - it 'should belong to a single user' do - Rate.should have_association(:user, :belongs_to) - end - - it 'should belong to a single project' do - Rate.should have_association(:project, :belongs_to) - end - -end - -describe Rate, 'locked?' do - it 'should be true if a Time Entry is associated' do - rate = Rate.new - rate.time_entries << mock_model(TimeEntry) - rate.locked?.should be_true - end - - it 'should be false if no Time Entries are associated' do - rate = Rate.new - rate.locked?.should be_false - end - -end - -describe Rate, 'locked?' do - it 'should be false if a Time Entry is associated' do - rate = Rate.new - rate.time_entries << mock_model(TimeEntry) - rate.unlocked?.should be_false - end - - it 'should be true if no Time Entries are associated' do - rate = Rate.new - rate.unlocked?.should be_true - end - -end - -describe Rate, 'save' do - include RateSpecHelper - - it 'should save if a Rate is unlocked' do - rate = Rate.new(rate_valid_attributes) - rate.stub!(:locked?).and_return(false) - rate.save.should eql(true) - end - - it 'should not save if a Rate is locked' do - rate = Rate.new(rate_valid_attributes) - rate.stub!(:locked?).and_return(true) - rate.save.should eql(false) - end -end - -describe Rate, 'destroy' do - include RateSpecHelper - - it 'should destroy the Rate if it is unlocked' do - rate = Rate.create(rate_valid_attributes) - rate.stub!(:locked?).and_return(false) - proc { - rate.destroy - }.should change(Rate, :count).by(-1) - - end - - it 'should not destroy the Rate if it is locked' do - rate = Rate.create(rate_valid_attributes) - rate.stub!(:locked?).and_return(true) - proc { - rate.destroy - }.should_not change(Rate, :count) - end -end - -describe Rate, 'for' do - before(:each) do - @user = mock_model(User) - @project = mock_model(Project) - @date = '2009-01-01' - @rate = mock_model(Rate, :amount => 50.50) - end - - describe 'parameters' do - it 'should be passed user' do - lambda {Rate.for}.should raise_error(ArgumentError) - end - - it 'can be passed an optional project' do - lambda {Rate.for(@user)}.should_not raise_error(ArgumentError) - lambda {Rate.for(@user, @project)}.should_not raise_error(ArgumentError) - end - - it 'can be passed an optional date string' do - lambda {Rate.for(@user)}.should_not raise_error(ArgumentError) - lambda {Rate.for(@user, nil, @date)}.should_not raise_error(ArgumentError) - end - - end - - describe 'returns' do - it 'a Rate object when there is a rate' do - Rate.stub!(:for_user_project_and_date).with(@user, @project, @date).and_return(@rate) - Rate.for(@user, @project, @date).should eql(@rate) - end - - it 'a nil when there is no rate' do - Rate.for(@user, @project, @date).should be_nil - end - end - - describe 'with a user, project, and date' do - it 'should find the rate for a user on the project before the date' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, @date).and_return(@rate) - Rate.for(@user, @project, @date) - end - - it 'should return the most recent rate found' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, @date).and_return(@rate) - Rate.for(@user, @project, @date).should eql(@rate) - end - - it 'should check for a default rate if no rate is found' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, @date).and_return(nil) - Rate.should_receive(:default_for_user_and_date).with(@user, @date).and_return(@rate) - Rate.for(@user, @project, @date).should eql(@rate) - end - - it 'should return nil if no set or default rate is found' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, @date).and_return(nil) - Rate.should_receive(:default_for_user_and_date).with(@user, @date).and_return(nil) - Rate.for(@user, @project, @date).should be_nil - end - end - - describe 'with a user and project' do - it 'should find the rate for a user on the project before today' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, Date.today.to_s).and_return(@rate) - Rate.for(@user, @project) - end - - it 'should return the most recent rate found' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, Date.today.to_s).and_return(@rate) - Rate.for(@user, @project).should eql(@rate) - end - - it 'should return nil if no set or default rate is found' do - Rate.should_receive(:for_user_project_and_date).with(@user, @project, Date.today.to_s).and_return(nil) - Rate.should_receive(:default_for_user_and_date).with(@user, Date.today.to_s).and_return(nil) - Rate.for(@user, @project).should be_nil - end - end - - describe 'with a user' do - it 'should find the rate without a project for a user on the project before today' do - Rate.should_receive(:for_user_project_and_date).with(@user, nil, Date.today.to_s).and_return(@rate) - Rate.for(@user) - end - - it 'should return the most recent rate found' do - Rate.should_receive(:for_user_project_and_date).with(@user, nil, Date.today.to_s).and_return(@rate) - Rate.for(@user).should eql(@rate) - end - - it 'should return nil if no set or default rate is found' do - Rate.should_receive(:for_user_project_and_date).with(@user, nil, Date.today.to_s).and_return(nil) - Rate.for(@user).should be_nil - end - end - - it 'with an invalid user should raise an InvalidParameterException' do - object = mock('random_object_with_id_attribute') - Rate.should_not_receive(:for_user_project_and_date) - lambda { - Rate.for(object) - }.should raise_error(Rate::InvalidParameterException, "user must be a Principal instance") - end - - it 'with an invalid project should raise an InvalidParameterException' do - object = mock('random_object_with_id_attribute') - Rate.should_not_receive(:for_user_project_and_date) - lambda { - Rate.for(@user, object) - }.should raise_error(Rate::InvalidParameterException, "project must be a Project instance") - end - - it 'with an invalid object for date should raise an InvalidParameterException' do - object = mock('random_object_thats_not_a_string') - Rate.should_not_receive(:for_user_project_and_date) - lambda { - Rate.for(@user, @project, object) - }.should raise_error(Rate::InvalidParameterException, "date must be a valid Date string (e.g. YYYY-MM-DD)") - end - - it 'with an invalid date string should raise an InvalidParameterException' do - Rate.should_not_receive(:for_user_project_and_date) - lambda { - Rate.for(@user, @project, '2000-13-40') - }.should raise_error(Rate::InvalidParameterException, "date must be a valid Date string (e.g. YYYY-MM-DD)") - end - - - -end - -describe Rate, 'for_user_project_and_date (private)' do - before(:each) do - @user = mock_model(User) - @project = mock_model(Project) - @date = '2009-01-01' - @rate = mock_model(Rate, :amount => 50.50) - end - - it 'should find the rate for a user on the project before the date' do - Rate.should_receive(:find).with(:first, { - :conditions => ["user_id IN (?) AND project_id IN (?) AND date_in_effect <= ?", - @user.id, - @project.id, - @date - ], - :order => 'date_in_effect DESC' - }).and_return(@rate) - - Rate.send(:for_user_project_and_date, @user, @project, @date) - end - - it 'should return the value of the most recent rate found' do - Rate.should_receive(:find).with(:first, { - :conditions => ["user_id IN (?) AND project_id IN (?) AND date_in_effect <= ?", - @user.id, - @project.id, - @date - ], - :order => 'date_in_effect DESC' - }).and_return(@rate1) - Rate.send(:for_user_project_and_date, @user, @project, @date).should eql(@rate1) - end - - it 'should search rates without a project when +project+ is nil' do - Rate.should_receive(:find).with(:first, { - :conditions => ["user_id IN (?) AND date_in_effect <= ? AND project_id IS NULL", - @user.id, - @date - ], - :order => 'date_in_effect DESC' - }).and_return(@rate1) - Rate.send(:for_user_project_and_date, @user, nil, @date).should eql(@rate1) - end -end diff --git a/test/unit/rate_test.rb b/test/unit/rate_test.rb new file mode 100644 index 0000000..89bce69 --- /dev/null +++ b/test/unit/rate_test.rb @@ -0,0 +1,225 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class RateTest < ActiveSupport::TestCase + def rate_valid_attributes + { + :user => User.generate!, + :project => Project.generate!, + :date_in_effect => Date.new(Date.today.year, 1, 1), + :amount => 100.50 + } + end + + should_belong_to :project + should_belong_to :user + should_have_many :time_entries + + should_validate_presence_of :user_id + should_validate_presence_of :date_in_effect + should_validate_numericality_of :amount + + + context '#locked?' do + should 'should be true if a Time Entry is associated' do + rate = Rate.new + rate.time_entries << TimeEntry.generate! + assert rate.locked? + end + + should 'should be false if no Time Entries are associated' do + rate = Rate.new + assert ! rate.locked? + end + end + + + context '#unlocked?' do + should 'should be false if a Time Entry is associated' do + rate = Rate.new + rate.time_entries << TimeEntry.generate! + assert ! rate.unlocked? + end + + should 'should be true if no Time Entries are associated' do + rate = Rate.new + assert rate.unlocked? + end + + end + + context '#save' do + + should 'should save if a Rate is unlocked' do + rate = Rate.new(rate_valid_attributes) + assert rate.save + end + + should 'should not save if a Rate is locked' do + rate = Rate.new(rate_valid_attributes) + rate.time_entries << TimeEntry.generate! + assert !rate.save + end + end + + + + + context '#destroy' do + + should 'should destroy the Rate if should is unlocked' do + rate = Rate.create(rate_valid_attributes) + assert_difference('Rate.count', -1) do + rate.destroy + end + + end + + should 'should not destroy the Rate if should is locked' do + rate = Rate.create(rate_valid_attributes) + rate.time_entries << TimeEntry.generate! + + assert_difference('Rate.count', 0) do + rate.destroy + end + end + end + + context '#for' do + setup do + @user = User.generate! + @project = Project.generate! + @date = '2009-01-01' + @date = Date.new(Date.today.year, 1, 1).to_s + @default_rate = Rate.generate!(:amount => 100.10, :date_in_effect => @date, :project => nil, :user => @user) + @rate = Rate.generate!(:amount => 50.50, :date_in_effect => @date, :project => @project, :user => @user) + end + + context 'parameters' do + should 'should be passed user' do + assert_raises ArgumentError do + Rate.for + end + end + + should 'can be passed an optional project' do + assert_nothing_raised do + Rate.for(@user) + end + + assert_nothing_raised do + Rate.for(@user, @project) + end + end + + should 'can be passed an optional date string' do + assert_nothing_raised do + Rate.for(@user) + end + + assert_nothing_raised do + Rate.for(@user, nil, @date) + end + end + + end + + context 'returns' do + should 'a Rate object when there is a rate' do + assert_equal @rate, Rate.for(@user, @project, @date) + end + + should 'a nil when there is no rate' do + assert @rate.destroy + assert @default_rate.destroy + + assert_equal nil, Rate.for(@user, @project, @date) + end + end + + context 'with a user, project, and date' do + should 'should find the rate for a user on the project before the date' do + assert_equal @rate, Rate.for(@user, @project, @date) + end + + should 'should return the most recent rate found' do + assert_equal @rate, Rate.for(@user, @project, @date) + end + + should 'should check for a default rate if no rate is found' do + assert @rate.destroy + + assert_equal @default_rate, Rate.for(@user, @project, @date) + end + + should 'should return nil if no set or default rate is found' do + assert @rate.destroy + assert @default_rate.destroy + + assert_equal nil, Rate.for(@user, @project, @date) + end + end + + context 'with a user and project' do + should 'should find the rate for a user on the project before today' do + assert_equal @rate, Rate.for(@user, @project) + end + + should 'should return the most recent rate found' do + assert_equal @rate, Rate.for(@user, @project) + end + + should 'should return nil if no set or default rate is found' do + assert @rate.destroy + assert @default_rate.destroy + + assert_equal nil, Rate.for(@user, @project) + end + end + + context 'with a user' do + should 'should find the rate without a project for a user on the project before today' do + assert_equal @default_rate, Rate.for(@user) + end + + should 'should return the most recent rate found' do + assert_equal @default_rate, Rate.for(@user) + end + + should 'should return nil if no set or default rate is found' do + assert @rate.destroy + assert @default_rate.destroy + + assert_equal nil, Rate.for(@user) + end + end + + should 'with an invalid user should raise an InvalidParameterException' do + object = Object.new + assert_raises Rate::InvalidParameterException do + Rate.for(object) + end + end + + should 'with an invalid project should raise an InvalidParameterException' do + object = Object.new + assert_raises Rate::InvalidParameterException do + Rate.for(@user, object) + end + end + + should 'with an invalid object for date should raise an InvalidParameterException' do + object = Object.new + assert_raises Rate::InvalidParameterException do + Rate.for(@user, @project, object) + end + end + + should 'with an invalid date string should raise an InvalidParameterException' do + assert_raises Rate::InvalidParameterException do + Rate.for(@user, @project, '2000-13-40') + end + end + + end + +end