diff --git a/spec/models/todo_spec.rb b/spec/models/todo_spec.rb new file mode 100644 index 00000000..410860a1 --- /dev/null +++ b/spec/models/todo_spec.rb @@ -0,0 +1,196 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') + +describe Todo do + def valid_attributes(attributes={}) + { + :description => "don't forget the milk", + :context => mock_model(Context, :name => 'errands') + }.merge(attributes) + end + + def create_todo(attributes={}) + todo = Todo.new(valid_attributes(attributes)) + todo.stub!(:user).and_return(mock_model(User, :date => Time.now)) + todo.save! + todo + end + + before(:each) do + @todo = Todo.new + end + + it_should_belong_to :context + it_should_belong_to :project + it_should_belong_to :user + + it_should_validate_presence_of :description + it_should_validate_presence_of :context + it_should_validate_length_of :description, :maximum => 100 + it_should_validate_length_of :notes, :maximum => 60_000 + + it 'validates presence of show_from when deferred' + + it 'ensures that show_from is a date in the future' do + todo = Todo.new(valid_attributes) + todo.stub!(:user).and_return(mock_model(User, :date => Time.now)) + todo.show_from = 3.days.ago + todo.should have(1).error_on(:show_from) + end + + it 'allows show_from to be blank' do + todo = Todo.new(valid_attributes(:show_from => '')) + todo.should_not have(:any).error_on(:show_from) + end + + describe 'states' do + it 'is active on initializing' do + create_todo.should be_active + end + + it 'is deferred when show from is in the future' do + create_todo(:show_from => 1.week.from_now).should be_deferred + end + + describe 'active' do + %w(project_hidden completed deferred).each do |from_state| + it "is activable from `#{from_state}'" do + todo = create_todo + todo.state = from_state + todo.send("#{from_state}?").should be_true + todo.activate! + todo.should be_active + end + end + + it 'clears show_from when entering active state' do + todo = create_todo + todo.show_from = 3.days.from_now + todo.should be_deferred + todo.activate! + todo.should be_active + todo.show_from.should be_nil + end + + it 'clears completed_at when entering active state' do + todo = create_todo + todo.complete! + todo.should be_completed + todo.activate! + todo.should be_active + todo.completed_at.should be_nil + end + end + + describe 'completed' do + %w(active project_hidden deferred).each do |from_state| + it "is completable from `#{from_state}'" do + todo = create_todo + todo.state = from_state + todo.send("#{from_state}?").should be_true + todo.complete! + todo.should be_completed + end + end + + it 'sets complated_at' do + todo = create_todo + todo.complete! + todo.completed_at.should_not be_nil + end + end + + describe 'project_hidden' do + %w(active deferred).each do |from_state| + it "is hiddable from `#{from_state}'" do + todo = create_todo + todo.state = from_state + todo.send("#{from_state}?").should be_true + todo.hide! + todo.should be_project_hidden + end + end + + it 'unhides to deferred when if show_from' do + todo = create_todo(:show_from => 4.days.from_now) + todo.hide! + todo.should be_project_hidden + todo.unhide! + todo.should be_deferred + end + + it 'unhides to active when not show_from' do + todo = create_todo(:show_from => '') + todo.hide! + todo.should be_project_hidden + todo.unhide! + todo.should be_active + end + end + + it "is deferrable from `active'" do + todo = create_todo + todo.activate! + todo.should be_active + todo.defer! + todo.should be_deferred + end + end + + describe 'when toggling completion' do + it 'toggles to active when completed' do + todo = create_todo + todo.complete! + todo.should be_completed + todo.toggle_completion! + todo.should be_active + end + + it 'toggles to completed when not completed' do + todo = create_todo + todo.should_not be_completed + todo.toggle_completion! + todo.should be_completed + end + end + + describe 'when retrieving project' do + it 'returns project if set' do + project = mock_model(Project) + todo = Todo.new(:project => project) + todo.project.should == project + end + + it 'returns a NullProject if not set' do + Todo.new.project.should be_an_instance_of(NullProject) + end + end + + describe('when setting show_from') { it 'is speced' } + + it 'is starred if tag is "starred"' do + todo = create_todo + todo.should_not be_starred + todo.add_tag('starred') + todo.reload + todo.should be_starred + end + + describe 'when toggling star flag' do + it 'toggles to not starred when starred' do + todo = create_todo + todo.add_tag('starred') + todo.should be_starred + todo.toggle_star! + todo.reload + todo.should_not be_starred + end + + it 'toggles to starred when not starred' do + todo = create_todo + todo.should_not be_starred + todo.toggle_star! + todo.reload + todo.should be_starred + end + end +end