move tests to new directory

This commit is contained in:
Reinier Balt 2013-05-11 23:13:16 +02:00
parent 65859807ea
commit 0bc9b0397a
42 changed files with 23 additions and 32 deletions

0
test/models/.gitkeep Normal file
View file

100
test/models/context_test.rb Normal file
View file

@ -0,0 +1,100 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class ContextTest < ActiveSupport::TestCase
fixtures :contexts, :todos, :recurring_todos, :users, :preferences
def setup
@agenda = contexts(:agenda)
@email = contexts(:email)
@library = contexts(:library)
end
def test_uses_acts_as_list
# only check that acts_as_list is present in the model
assert @agenda.respond_to?(:move_to_bottom)
end
def test_validate_presence_of_name
@agenda.name = ""
assert !@agenda.save
assert_equal 1, @agenda.errors.count
assert_equal "context must have a name", @agenda.errors[:name][0]
end
def test_validate_name_is_less_than_256
@agenda.name = generate_random_string(256)
assert !@agenda.save
assert_equal 1, @agenda.errors.count
assert_equal "context name must be less than 256 characters", @agenda.errors[:name][0]
end
def test_validate_name_is_unique
newcontext = Context.new
newcontext.name = contexts(:agenda).name
newcontext.user_id = contexts(:agenda).user_id
assert !newcontext.save
assert_equal 1, newcontext.errors.count
assert_equal "already exists", newcontext.errors[:name][0]
end
def test_delete_context_deletes_todos_within_it
assert_equal 7, @agenda.todos.count
agenda_todo_ids = @agenda.todos.collect{|t| t.id }
@agenda.destroy
agenda_todo_ids.each do |todo_id|
assert !Todo.exists?(todo_id)
end
end
def test_to_param_returns_id
assert_equal '1', @agenda.to_param
end
def test_title_reader_returns_name
assert_equal @agenda.name, @agenda.title
end
def test_null_object
c = Context.null_object
assert c.nil?
assert_nil c.id
assert_equal '', c.name
end
def test_new_record_before_save
assert !@agenda.new_record_before_save?, "existing records should not be new_record"
c = Context.where(:name => "I do not exist").first_or_create
assert c.new_record_before_save?, "newly created record should be new_record"
end
def test_hide_context
assert @agenda.active?
@agenda.hide!
assert @agenda.hidden?
end
def test_closing_context_guarded_for_active_todos
assert @agenda.active?
assert AASM::InvalidTransition do
@agenda.close!
end
@agenda.todos.active.each {|t| t.complete! }
@agenda.close!
assert @agenda.closed?
end
def test_activating_closed_context
# given a context @agenda that is closed
@agenda.todos.active.each {|t| t.complete! }
@agenda.close!
assert @agenda.closed?
# when I activate @agenda
@agenda.activate!
# then @agenda should have an active state
assert @agenda.active?
end
end

View file

@ -0,0 +1,46 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class IsTaggableTest < ActiveSupport::TestCase
fixtures :todos, :recurring_todos
def test_models_are_taggable
assert Todo.first.respond_to?(:tag_list)
assert RecurringTodo.first.respond_to?(:tag_list)
end
def test_test_to_s
t = Todo.create(:description => "test", :context => Context.first)
t.tag_list = "one, two, three"
# tags will be sorted alphabetical
assert_equal "one, three, two", t.tag_list
assert_equal "one, three, two", t.tags.to_s
end
def test_getting_all_tags_except_starred
t = Todo.create(:description => "test", :context => Context.first)
t.tag_list = "one, two, three"
t.toggle_star!
assert_equal "one, starred, three, two", t.tag_list
assert_equal "one, three, two", t.tags.all_except_starred.map(&:name).sort.join(", ")
end
def test_editing_tags
t = Todo.create(:description => "test", :context => Context.first)
t.tag_list = "a, b, c"
assert_equal 3, t.tags.count
t.tag_with "a, b"
assert_equal "a, b", t.tag_list, "should remove tag c"
t.tag_with "a, b, c, d"
assert_equal "a, b, c, d", t.tag_list, "should add c and d"
t.tag_with "a, b, e, f"
assert_equal "a, b, e, f", t.tag_list, "should add e and f and remove c and d"
end
end

14
test/models/notes_test.rb Normal file
View file

@ -0,0 +1,14 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class NotesTest < ActiveSupport::TestCase
fixtures :notes
def setup
@notes = Note.find(1)
end
# Replace this with your real tests.
def test_truth
assert_kind_of Note, @notes
end
end

View file

@ -0,0 +1,84 @@
require File.expand_path(File.dirname(__FILE__) + '/../minimal_test_helper')
require 'app/models/stats/pie_chart_data'
require 'active_support/core_ext/string'
class Stats::PieChartDataTest < Test::Unit::TestCase
def setup
xx = { :stats => { :other_actions_label => '(other)' } }
I18n.backend.store_translations(:xx, xx)
I18n.locale = :xx
end
def test_with_0_items
data = Stats::PieChartData.new([], 'a chart', 50)
assert_equal [], data.values
assert_equal [], data.labels
assert_equal [], data.ids
end
def test_with_less_than_10_items
items = [
{'id' => 1, 'name' => 'one', 'total' => 11},
{'id' => 2, 'name' => 'two', 'total' => 4},
{'id' => 3, 'name' => 'three', 'total' => 8},
{'id' => 4, 'name' => 'four', 'total' => 13},
{'id' => 5, 'name' => 'five', 'total' => 20},
{'id' => 6, 'name' => 'six', 'total' => 17},
{'id' => 7, 'name' => 'seven', 'total' => 5},
{'id' => 8, 'name' => 'eight', 'total' => 1},
{'id' => 9, 'name' => 'nine', 'total' => 6}
]
data = Stats::PieChartData.new(items, 'a chart', 50)
assert_equal [12, 4, 9, 15, 23, 20, 5, 1, 7], data.values
assert_equal ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"], data.labels
assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9], data.ids
end
def test_with_exactly_10_items
items = [
{'id' => 1, 'name' => 'one', 'total' => 11},
{'id' => 2, 'name' => 'two', 'total' => 4},
{'id' => 3, 'name' => 'three', 'total' => 8},
{'id' => 4, 'name' => 'four', 'total' => 13},
{'id' => 5, 'name' => 'five', 'total' => 20},
{'id' => 6, 'name' => 'six', 'total' => 17},
{'id' => 7, 'name' => 'seven', 'total' => 5},
{'id' => 8, 'name' => 'eight', 'total' => 1},
{'id' => 9, 'name' => 'nine', 'total' => 6},
{'id' => 10, 'name' => 'ten', 'total' => 19}
]
data = Stats::PieChartData.new(items, 'a chart', 50)
assert_equal [10, 3, 7, 12, 19, 16, 4, 0, 5, 18], data.values
assert_equal ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"], data.labels
assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], data.ids
end
def test_with_more_than_10_items
items = [
{'id' => 1, 'name' => 'one', 'total' => 11},
{'id' => 2, 'name' => 'two', 'total' => 4},
{'id' => 3, 'name' => 'three', 'total' => 8},
{'id' => 4, 'name' => 'four', 'total' => 13},
{'id' => 5, 'name' => 'five', 'total' => 20},
{'id' => 6, 'name' => 'six', 'total' => 17},
{'id' => 7, 'name' => 'seven', 'total' => 5},
{'id' => 8, 'name' => 'eight', 'total' => 1},
{'id' => 9, 'name' => 'nine', 'total' => 6},
{'id' => 10, 'name' => 'ten', 'total' => 19},
{'id' => 11, 'name' => 'eleven', 'total' => 14}
]
data = Stats::PieChartData.new(items, 'a chart', 50)
assert_equal [9, 3, 6, 11, 16, 14, 4, 0, 5, 27], data.values
assert_equal ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "(other)"], data.labels
assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, -1], data.ids
end
end

View file

@ -0,0 +1,34 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class PreferenceTest < ActiveSupport::TestCase
fixtures :users, :preferences
def setup
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
@admin_user = User.find(1)
@other_user = User.find(2)
end
def test_time_zone
assert_equal 'London', @admin_user.preference.time_zone
end
def test_show_project_on_todo_done
assert @other_user.preference.show_project_on_todo_done
assert !@admin_user.preference.show_project_on_todo_done
end
def test_parse_date
assert_equal @admin_user.at_midnight(Date.new(2007, 5, 20)).to_s, @admin_user.preference.parse_date('20/5/2007').to_s
end
def test_parse_date_returns_nil_if_string_is_empty
assert_nil @admin_user.preference.parse_date('')
end
def test_parse_date_returns_nil_if_string_is_nil
assert_nil @admin_user.preference.parse_date(nil)
end
end

View file

@ -0,0 +1,22 @@
require_relative '../test_helper'
require_relative '../../lib/project_from_todo'
class ProjectFromTodoTest < ActiveSupport::TestCase
fixtures :todos
def test_create_project_from_valid_todo
todo = todos(:upgrade_rails)
project = ProjectFromTodo.new(todo).create
assert_equal project.name, todo.description
assert_equal project.description, todo.notes
assert_equal project.default_context, todo.context
end
def test_invalid_project_from_invalid_todo
todo = todos(:upgrade_rails)
todo.description = ""
project = ProjectFromTodo.new(todo).create
assert_not_nil project
assert_equal false, project.valid?
end
end

241
test/models/project_test.rb Normal file
View file

@ -0,0 +1,241 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class ProjectTest < ActiveSupport::TestCase
fixtures :projects, :contexts, :todos, :recurring_todos, :users, :preferences
def setup
@timemachine = projects(:timemachine)
@moremoney = projects(:moremoney)
end
# associations
def test_has_default_context
assert !@timemachine.default_context.nil?
assert @timemachine.default_context.name == contexts(:lab).name
p = Project.new
assert_equal '', p.default_context.name
p.default_context = contexts(:agenda)
assert_equal 'agenda', p.default_context.name
end
# validations
def test_validate_presence_of_name
@timemachine.name = ""
assert !@timemachine.save
assert_equal 1, @timemachine.errors.count
assert_equal "project must have a name", @timemachine.errors[:name][0]
end
def test_validate_name_is_less_than_256
@timemachine.name = generate_random_string(256)
assert !@timemachine.save
assert_equal 1, @timemachine.errors.count
assert_equal "project name must be less than 256 characters", @timemachine.errors[:name][0]
end
def test_validate_name_is_unique
newproj = Project.new
newproj.name = projects(:timemachine).name
newproj.user_id = projects(:timemachine).user_id
assert !newproj.save
assert_equal 1, newproj.errors.count
assert_equal "already exists", newproj.errors[:name][0]
end
# state machine
def test_project_initial_state_is_active
assert_equal :active, @timemachine.aasm_current_state
assert @timemachine.active?
end
def test_hide_project
@timemachine.hide!
assert_equal :hidden, @timemachine.aasm_current_state
assert @timemachine.hidden?
end
def test_activate_project
@timemachine.activate!
assert_equal :active, @timemachine.aasm_current_state
assert @timemachine.active?
end
def test_transition_to_another_state
assert_equal :active, @timemachine.aasm_current_state
@timemachine.transition_to(:hidden)
assert_equal :hidden, @timemachine.aasm_current_state
@timemachine.transition_to(:completed)
assert_equal :completed, @timemachine.aasm_current_state
@timemachine.transition_to(:active)
assert_equal :active, @timemachine.aasm_current_state
end
def test_transition_to_same_state
assert_equal :active, @timemachine.aasm_current_state
@timemachine.transition_to(:active)
assert_equal :active, @timemachine.aasm_current_state
end
# other tests
def test_review_project
assert_nil @timemachine.last_reviewed
assert @timemachine.needs_review?(nil)
end
def test_review_completedprojects
@timemachine.complete!
assert !@timemachine.needs_review?(nil)
end
def test_complete_project
assert_nil @timemachine.completed_at
@timemachine.complete!
assert_equal :completed, @timemachine.aasm_current_state
assert @timemachine.completed?
assert_not_nil @timemachine.completed_at, "completed_at not expected to be nil"
assert_in_delta Time.now, @timemachine.completed_at, 1
end
def test_delete_project_deletes_todos_within_it
assert_equal 3, @timemachine.todos.count
timemachine_todo_ids = @timemachine.todos.map{ |t| t.id }
@timemachine.destroy
timemachine_todo_ids.each do |t_id|
assert !Todo.exists?(t_id)
end
end
def test_deferred_todos
assert_equal 1, @timemachine.todos.deferred.size
t = @timemachine.todos.not_completed[0]
t.show_from = 1.days.from_now.utc
t.save!
assert_equal 2, Project.find(@timemachine.id).todos.deferred.size
end
def test_to_param_returns_id
assert_equal '1', @timemachine.to_param
end
def test_null_object
p = Project.null_object
assert !p.hidden?
assert p.nil?
assert_nil p.id
assert_equal "", p.name
end
def test_name_removes_extra_spaces
newproj = Project.new
newproj.name = "These Words Have Proximity Issues "
assert newproj.save
assert_equal 0, newproj.errors.count
assert_equal "These Words Have Proximity Issues", newproj.name
# and on update...
@timemachine.name = " a time machine needs lots of spaaaaaaace "
assert @timemachine.save
assert_equal "a time machine needs lots of spaaaaaaace", @timemachine.name
end
def test_deferred_todo_count
assert_equal 1, @timemachine.todos.deferred.count
assert_equal 0, @moremoney.todos.deferred.count
first_todo = @moremoney.todos[0]
first_todo.show_from = Time.zone.now + 1.week
first_todo.save!
assert_equal :deferred, @moremoney.todos[0].aasm_current_state
assert_equal 1, @moremoney.todos.deferred.count
end
def test_done_todo_count
assert_equal 0, @timemachine.todos.completed.count
assert_equal 0, @moremoney.todos.completed.count
@moremoney.todos[0].complete!
assert_equal 1, @moremoney.todos.completed.count
end
def test_not_done_todo_count
assert_equal 3, @timemachine.todos.not_completed.count
assert_equal 4, @moremoney.todos.not_completed.count
@moremoney.todos[0].complete!
assert_equal 3, @moremoney.todos.not_completed.count
end
def test_new_record_before_save
assert !@timemachine.new_record_before_save?, "existing records should not be new_record"
p = Project.where(:name => "I do not exist").first_or_create
assert p.new_record_before_save?, "newly created record should be new_record"
end
def test_shortened_name
s = "project"*7 # len=49
p = users(:admin_user).projects.create(:name => s)
assert_equal 49, p.name.length
assert_equal 40, p.shortened_name.length
assert_equal "project"*5+"pr...", p.shortened_name
assert p.shortened_name.html_safe?
end
def test_note_count
p = users(:admin_user).projects.first
assert_not_nil p
assert_equal 2, p.note_count
p.notes.create(:user_id => p.user_id, :body => "new note")
assert_equal 3, p.note_count
end
def test_project_blocked
p = users(:admin_user).projects.first
todo_in_other_project = users(:admin_user).projects.last.todos.first
assert !p.blocked?, "first project should not be blocked"
p.complete!
assert !p.blocked?, "completed projects should not be blocked"
p.activate!
p.todos.each{|t| t.show_from = 2.weeks.from_now; t.save! }
assert p.blocked?, "projects with deferred todos should be blocked"
end
def test_project_stalled
p = users(:admin_user).projects.first
p.hide!
assert !p.stalled?, "hidden projects are not stalled"
p.complete!
assert !p.stalled?, "completed projects are not stalled"
p.activate!
p.todos.each{|t| t.complete!}
assert p.todos.reload.active.empty?, "project should not have active todos"
assert p.todos.reload.deferred_or_blocked.empty?, "there should not be deferred or blocked todos"
assert p.reload.stalled?, "project should be stalled"
end
def test_age_in_days
p1 = users(:admin_user).projects.create!(:name => "test1")
assert_equal 1, p1.age_in_days, "newly created project has age or one day"
p2 = users(:admin_user).projects.create!(:name => "test7")
p2.created_at = 1.week.ago
p2.save!
p2.reload
assert_equal 8, p2.age_in_days
end
end

View file

@ -0,0 +1,356 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class RecurringTodoTest < ActiveSupport::TestCase
def setup
@every_day = recurring_todos(:call_bill_gates_every_day)
@every_workday = recurring_todos(:call_bill_gates_every_workday)
@weekly_every_day = recurring_todos(:call_bill_gates_every_week)
@every_week = @weekly_every_day
@monthly_every_last_friday = recurring_todos(:check_with_bill_every_last_friday_of_month)
@every_month = @monthly_every_last_friday
@yearly = recurring_todos(:birthday_reinier)
@today = Time.now.utc
@tomorrow = @today + 1.day
@in_three_days = @today + 3.days
@in_four_days = @in_three_days + 1.day # need a day after start_from
@friday = Time.zone.local(2008,6,6)
@saturday = Time.zone.local(2008,6,7)
@sunday = Time.zone.local(2008,6,8) # june 8, 2008 was a sunday
@monday = Time.zone.local(2008,6,9)
@tuesday = Time.zone.local(2008,6,10)
@wednesday = Time.zone.local(2008,6,11)
@thursday = Time.zone.local(2008,6,12)
end
def test_pattern_text
assert_equal "every day", @every_day.recurrence_pattern
assert_equal "on work days", @every_workday.recurrence_pattern
assert_equal "every last friday of every 2 months", @monthly_every_last_friday.recurrence_pattern
assert_equal "every year on June 08", @yearly.recurrence_pattern
end
def test_daily_every_day
# every_day should return todays date if there was no previous date
due_date = @every_day.get_due_date(nil)
# use only day-month-year compare, because milisec / secs could be different
assert_equal_dmy @today, due_date
# when the last todo was completed today, the next todo is due tomorrow
due_date =@every_day.get_due_date(@today)
assert_equal @tomorrow, due_date
# do something every 14 days
@every_day.every_other1=14
due_date = @every_day.get_due_date(@today)
assert_equal @today+14.days, due_date
end
def test_daily_work_days
assert_equal @monday, @every_workday.get_due_date(@friday)
assert_equal @monday, @every_workday.get_due_date(@saturday)
assert_equal @monday, @every_workday.get_due_date(@sunday)
assert_equal @tuesday, @every_workday.get_due_date(@monday)
end
def test_show_from_date
# assume that target due_date works fine, i.e. don't do the same tests over
@every_day.target='show_from_date'
# when recurrence is targeted on show_from, due date shoult remain nil
assert_equal nil, @every_day.get_due_date(nil)
assert_equal nil, @every_day.get_due_date(@today-3.days)
# check show from get the next day
assert_equal_dmy @today, @every_day.get_show_from_date(@today-1.days)
assert_equal @today+1.day, @every_day.get_show_from_date(@today)
@every_day.target='due_date'
# when target on due_date, show_from is relative to due date unless show_always is true
@every_day.show_always = true
assert_equal nil, @every_day.get_show_from_date(@today-1.days)
@every_day.show_always = false
@every_day.show_from_delta=10
assert_equal_dmy @today, @every_day.get_show_from_date(@today+9.days) #today+1+9-10
# when show_from is 0, show_from is the same day it's due
@every_day.show_from_delta=0
assert_equal @every_day.get_due_date(@today+9.days), @every_day.get_show_from_date(@today+9.days)
# when show_from is nil, show always (happend in tests)
@every_day.show_from_delta=nil
assert_equal nil, @every_day.get_show_from_date(@today+9.days)
# TODO: show_from has no use case for daily pattern. Need to test on
# weekly/monthly/yearly
end
def test_end_date_on_recurring_todo
assert_equal true, @every_day.continues_recurring?(@in_three_days)
assert_equal true, @every_day.continues_recurring?(@in_four_days)
@every_day.end_date = @in_four_days
@every_day.ends_on = 'ends_on_end_date'
assert_equal false, @every_day.continues_recurring?(@in_four_days)
end
def test_weekly_every_day_setters
@weekly_every_day.every_day = ' '
@weekly_every_day.weekly_return_sunday=('s')
assert_equal 's ', @weekly_every_day.every_day
@weekly_every_day.weekly_return_monday=('m')
assert_equal 'sm ', @weekly_every_day.every_day
@weekly_every_day.weekly_return_tuesday=('t')
assert_equal 'smt ', @weekly_every_day.every_day
@weekly_every_day.weekly_return_wednesday=('w')
assert_equal 'smtw ', @weekly_every_day.every_day
@weekly_every_day.weekly_return_thursday=('t')
assert_equal 'smtwt ', @weekly_every_day.every_day
@weekly_every_day.weekly_return_friday=('f')
assert_equal 'smtwtf ', @weekly_every_day.every_day
@weekly_every_day.weekly_return_saturday=('s')
assert_equal 'smtwtfs', @weekly_every_day.every_day
# test remove
@weekly_every_day.weekly_return_wednesday=(' ')
assert_equal 'smt tfs', @weekly_every_day.every_day
end
def test_weekly_pattern
assert_equal true, @weekly_every_day.continues_recurring?(nil)
due_date = @weekly_every_day.get_due_date(@sunday)
assert_equal @monday, due_date
# saturday is last day in week, so the next date should be sunday + n-1 weeks
# n-1 because sunday is already in the next week
@weekly_every_day.every_other1 = 3
due_date = @weekly_every_day.get_due_date(@saturday)
assert_equal @sunday + 2.weeks, due_date
# remove tuesday and wednesday
@weekly_every_day.weekly_return_tuesday=(' ')
@weekly_every_day.weekly_return_wednesday=(' ')
assert_equal 'sm tfs', @weekly_every_day.every_day
due_date = @weekly_every_day.get_due_date(@monday)
assert_equal @thursday, due_date
@weekly_every_day.every_other1 = 1
@weekly_every_day.every_day = ' tw '
due_date = @weekly_every_day.get_due_date(@tuesday)
assert_equal @wednesday, due_date
due_date = @weekly_every_day.get_due_date(@wednesday)
assert_equal @tuesday+1.week, due_date
@weekly_every_day.every_day = ' s'
due_date = @weekly_every_day.get_due_date(@sunday)
assert_equal @saturday+1.week, due_date
end
def test_monthly_pattern
due_date = @monthly_every_last_friday.get_due_date(@sunday)
assert_equal Time.zone.local(2008,6,27), due_date
friday_is_last_day_of_month = Time.zone.local(2008,10,31)
due_date = @monthly_every_last_friday.get_due_date(friday_is_last_day_of_month-1.day )
assert_equal friday_is_last_day_of_month , due_date
@monthly_every_third_friday = @monthly_every_last_friday
@monthly_every_third_friday.every_other3=3 #third
due_date = @monthly_every_last_friday.get_due_date(@sunday) # june 8th 2008
assert_equal Time.zone.local(2008, 6, 20), due_date
# set date past third friday of this month
due_date = @monthly_every_last_friday.get_due_date(Time.zone.local(2008,6,21)) # june 21th 2008
assert_equal Time.zone.local(2008, 8, 15), due_date # every 2 months, so aug
@monthly = @monthly_every_last_friday
@monthly.recurrence_selector=0
@monthly.every_other1 = 8 # every 8th day of the month
@monthly.every_other2 = 2 # every 2 months
due_date = @monthly.get_due_date(@saturday) # june 7th
assert_equal @sunday, due_date # june 8th
due_date = @monthly.get_due_date(@sunday) # june 8th
assert_equal Time.zone.local(2008,8,8), due_date # aug 8th
end
def test_yearly_pattern
# beginning of same year
due_date = @yearly.get_due_date(Time.zone.local(2008,2,10)) # feb 10th
assert_equal @sunday, due_date # june 8th
# same month, previous date
due_date = @yearly.get_due_date(@saturday) # june 7th
show_from_date = @yearly.get_show_from_date(@saturday) # june 7th
assert_equal @sunday, due_date # june 8th
assert_equal @sunday-5.days, show_from_date
# same month, day after
due_date = @yearly.get_due_date(@monday) # june 9th
assert_equal Time.zone.local(2009,6,8), due_date # june 8th next year
# very overdue
due_date = @yearly.get_due_date(@monday+5.months-2.days) # november 7
assert_equal Time.zone.local(2009,6,8), due_date # june 8th next year
@yearly.recurrence_selector = 1
@yearly.every_other3 = 2 # second
@yearly.every_count = 3 # wednesday
# beginning of same year
due_date = @yearly.get_due_date(Time.zone.local(2008,2,10)) # feb 10th
assert_equal Time.zone.local(2008,6,11), due_date # june 11th
# same month, before second wednesday
due_date = @yearly.get_due_date(@saturday) # june 7th
assert_equal Time.zone.local(2008,6,11), due_date # june 11th
# same month, after second wednesday
due_date = @yearly.get_due_date(Time.zone.local(2008,6,12)) # june 7th
assert_equal Time.zone.local(2009,6,10), due_date # june 10th
end
def test_next_todo_without_previous_todo
# test handling of nil as previous
#
# start_from is way_back
due_date1 = @yearly.get_due_date(nil)
due_date2 = @yearly.get_due_date(Time.now.utc + 1.day)
assert_equal due_date1, due_date2
# start_from is in the future
@yearly.start_from = Time.now.utc + 1.week
due_date1 = @yearly.get_due_date(nil)
due_date2 = @yearly.get_due_date(Time.now.utc + 1.day)
assert_equal due_date1, due_date2
# start_from is nil
@yearly.start_from = nil
due_date1 = @yearly.get_due_date(nil)
due_date2 = @yearly.get_due_date(Time.now.utc + 1.day)
assert_equal due_date1, due_date2
end
def test_last_sunday_of_march
@yearly.recurrence_selector = 1
@yearly.every_other2 = 3 # march
@yearly.every_other3 = 5 # last
@yearly.every_count = 0 # sunday
due_date = @yearly.get_due_date(Time.zone.local(2008,10,1)) # oct 1st
assert_equal Time.zone.local(2009,3,29), due_date # march 29th
end
def test_start_from_in_future
# every_day should return start_day if it is in the future
@every_day.start_from = @in_three_days
due_date = @every_day.get_due_date(nil)
assert_equal @in_three_days, due_date
due_date = @every_day.get_due_date(@tomorrow)
assert_equal @in_three_days, due_date
# if we give a date in the future for the previous todo, the next to do
# should be based on that future date.
due_date = @every_day.get_due_date(@in_four_days)
assert_equal @in_four_days+1.day, due_date
@weekly_every_day.start_from = Time.zone.local(2020,1,1)
assert_equal Time.zone.local(2020,1,1), @weekly_every_day.get_due_date(nil)
assert_equal Time.zone.local(2020,1,1), @weekly_every_day.get_due_date(Time.zone.local(2019,10,1))
assert_equal Time.zone.local(2020,1,10), @weekly_every_day.get_due_date(Time.zone.local(2020,1,9))
@monthly_every_last_friday.start_from = Time.zone.local(2020,1,1)
assert_equal Time.zone.local(2020,1,31), @monthly_every_last_friday.get_due_date(nil) # last friday of jan
assert_equal Time.zone.local(2020,1,31), @monthly_every_last_friday.get_due_date(Time.zone.local(2019,12,1)) # last friday of jan
assert_equal Time.zone.local(2020,2,28), @monthly_every_last_friday.get_due_date(Time.zone.local(2020,2,1)) # last friday of feb
# start from after june 8th 2008
@yearly.start_from = Time.zone.local(2020,6,12)
assert_equal Time.zone.local(2021,6,8), @yearly.get_due_date(nil) # jun 8th next year
assert_equal Time.zone.local(2021,6,8), @yearly.get_due_date(Time.zone.local(2019,6,1)) # also next year
assert_equal Time.zone.local(2021,6,8), @yearly.get_due_date(Time.zone.local(2020,6,15)) # also next year
this_year = Time.now.utc.year
@yearly.start_from = Time.zone.local(this_year+1,6,12)
due_date = @yearly.get_due_date(nil)
assert_equal due_date.year, this_year+2
end
def test_toggle_completion
assert @yearly.active?
assert @yearly.toggle_completion!
assert @yearly.completed?
# entering completed state should set completed_at
assert !@yearly.completed_at.nil?
assert @yearly.toggle_completion!
assert @yearly.active?
# re-entering active state should clear completed_at
assert @yearly.completed_at.nil?
end
def test_starred
@yearly.tag_with("1, 2, starred")
@yearly.tags.reload
assert @yearly.starred?
assert !@weekly_every_day.starred?
@yearly.toggle_star!
assert !@yearly.starred?
@yearly.toggle_star!
assert @yearly.starred?
end
def test_occurence_count
@every_day.number_of_occurences = 2
assert_equal true, @every_day.continues_recurring?(@in_three_days)
@every_day.increment_occurrences
assert_equal true, @every_day.continues_recurring?(@in_three_days)
@every_day.increment_occurrences
assert_equal false, @every_day.continues_recurring?(@in_three_days)
# after completion, when you reactivate the recurring todo, the occurences
# count should be reset
assert_equal 2, @every_day.occurences_count
assert @every_day.toggle_completion!
assert @every_day.toggle_completion!
assert_equal true, @every_day.continues_recurring?(@in_three_days)
assert_equal 0, @every_day.occurences_count
end
def test_invalid_recurring_period_will_not_save
@every_day.recurring_period = 'invalid'
assert !@every_day.valid?
@every_month.recurrence_selector = 99
assert_raise(Exception){ @every_month.valid? }
@yearly.recurrence_selector = 99
assert_raise(Exception){ @yearly.valid? }
end
def test_every_n_the_day_must_be_filled
@every_day.every_other1 = nil
assert !@every_day.valid?
end
def test_every_n_week_must_be_filled
@every_week.every_other1 = nil
assert !@every_week.valid?
end
def test_every_n_month_must_be_filled
@every_month.every_other1 = nil
@every_month.every_other2 = nil
assert !@every_month.valid?
@every_month.recurrence_selector = 0
assert !@every_month.valid?
end
end

View file

@ -0,0 +1,57 @@
require_relative '../minimal_test_helper'
require_relative '../../lib/staleness'
class StalenessTest < Test::Unit::TestCase
FakeUser = Struct.new(:time)
FakeTask = Struct.new(:due, :completed, :created_at) do
def completed?
self.completed
end
end
def now
@now ||= Time.utc(2013, 2, 28, 0, 0, 0)
end
def after_now
@after_now ||= Time.utc(2013, 3, 1, 0, 0, 0)
end
def day16
@day16 ||= Time.utc(2013, 2, 12, 0, 0, 0)
end
def day8
@day8 ||= Time.utc(2013, 2, 20, 0, 0, 0)
end
def setup
@current_user = FakeUser.new(now)
end
def test_item_with_due_date_is_not_stale_ever
todo = FakeTask.new(now, false, day8)
assert_equal 0, Staleness.days_stale(todo, @current_user)
end
def test_complete_item_is_not_stale
todo = FakeTask.new(day8, true, day16)
assert_equal 0, Staleness.days_stale(todo, @current_user)
end
def test_created_at_after_current_time_is_not_stale
todo = FakeTask.new(nil, false, after_now)
assert_equal 0, Staleness.days_stale(todo, @current_user)
end
def test_young_item_is_not_stale
todo = FakeTask.new(nil, false, now)
assert_equal 0, Staleness.days_stale(todo, @current_user)
end
def test_todo_staleness_calculation
todo = FakeTask.new(nil, false, day8)
assert_equal 8, Staleness.days_stale(todo, @current_user)
end
end

View file

@ -0,0 +1,31 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class TagCloudQueryTest < ActiveSupport::TestCase
fixtures :tags, :taggings, :users
def user
@user ||= User.find 1
end
def test_get_all_tags
tags = Stats::TagCloudQuery.new(user).result
assert_equal 2, tags.size
tags.sort_by! {|t| t.id}
tag = tags.first
assert_equal 3, tag.count
assert_equal "foo", tag.name
tag = tags.last
assert_equal 1, tag.count
assert_equal "bar", tag.name
end
def test_get_subset_of_tags
tags = Stats::TagCloudQuery.new(user, 1.week.ago).result
assert_equal 1, tags.size
assert_equal 2, tags.first.count
assert_equal "foo", tags.first.name
end
end

View file

@ -0,0 +1,31 @@
require File.expand_path(File.dirname(__FILE__) + '/../minimal_test_helper')
require 'app/models/stats/tag_cloud'
class TagCloudTest < Test::Unit::TestCase
FakeTag = Struct.new(:name, :count)
def test_tags_get_sorted_alphabetically
tags = [FakeTag.new("bee", 1), FakeTag.new("See", 10), FakeTag.new("aye", 100)]
assert_equal %w(aye bee See), Stats::TagCloud.new(tags).tags.map(&:name)
end
def test_tag_relative_size
tags = [FakeTag.new("bee", 1), FakeTag.new("See", 10), FakeTag.new("aye", 100)]
cloud = Stats::TagCloud.new(tags)
assert_equal 0, cloud.relative_size(FakeTag.new("whatever", 1))
assert_equal 4, cloud.relative_size(FakeTag.new("whatever", 50))
assert_equal 9, cloud.relative_size(FakeTag.new("whatever", 100))
end
def test_empty_tags
cloud = Stats::TagCloud.new([])
assert cloud.empty?
cloud = Stats::TagCloud.new([FakeTag.new("Tag", 1)])
assert !cloud.empty?
end
end

54
test/models/tag_test.rb Normal file
View file

@ -0,0 +1,54 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class TagTest < ActiveSupport::TestCase
fixtures :tags
def test_find_or_create_with_single_word
tag = Tag.where(:name => "test").first_or_create
assert !tag.new_record?
end
def test_find_or_create_with_space
tag = Tag.where(:name => "test test").first_or_create
assert !tag.new_record?
end
def test_find_or_create_with_dot
tag = Tag.where(:name => "a.b.c").first_or_create
assert !tag.new_record?
end
def test_find_or_create_with_number_as_string
tag = Tag.where(:name => "12343").first_or_create
assert !tag.new_record?
tag = Tag.where(:name => "8.1.2").first_or_create
assert !tag.new_record?
end
def test_tag_name_always_lowercase
tag = Tag.where(:name => "UPPER").first_or_create
assert !tag.new_record?
upper = Tag.where(:name => "upper").first
assert_not_nil upper
assert upper.name == "upper"
end
def test_tag_name_stripped_of_spaces
tag = Tag.where(:name => " strip spaces ").first_or_create
assert !tag.new_record?
assert tag.name == "strip spaces"
end
def test_tag_label
assert_equal 'one-two-three', Tag.new(:name => 'one two three').label
end
def test_tag_as_string
tags = [Tag.new(:name => 'tag1'), Tag.new(:name => 'tag2')]
assert_equal 'tag1, tag2', tags.join(', ')
end
end

View file

@ -0,0 +1,16 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class TaggingTest < ActiveSupport::TestCase
fixtures :taggings, :tags
def test_removes_unused_tags
tag = Tag.create!(:name => "hello")
tagging = Tagging.create!(:tag => tag, :taggable_id => 1)
assert_equal 1, Tagging.find(:all, :conditions => ["tag_id = ?", tag.id]).count
tagging.destroy
assert_nil Tag.where(:name => "hello").first
end
end

View file

@ -0,0 +1,93 @@
require 'date'
require 'time'
require './test/minimal_test_helper'
require 'app/models/stats/time_to_complete'
FakeTask = Struct.new(:created_at, :completed_at)
class TimeToCompleteTest < Test::Unit::TestCase
def now
@now ||= Time.utc(2013, 1, 2, 3, 4, 5)
end
def day0
@day0 ||= Time.utc(2013, 1, 2, 0, 0, 0)
end
def day2
@day2 ||= Time.utc(2012, 12, 31, 0, 0, 0)
end
def day4
@day4 ||= Time.utc(2012, 12, 29, 0, 0, 0)
end
def day6
@day6 ||= Time.utc(2012, 12, 27, 0, 0, 0)
end
def fake_tasks
@fake_tasks ||= [
FakeTask.new(day2, now),
FakeTask.new(day4, now),
FakeTask.new(day6, now)
]
end
def test_empty_minimum
assert_equal 0, Stats::TimeToComplete.new([]).min
end
def test_empty_maximum
assert_equal 0, Stats::TimeToComplete.new([]).max
end
def test_empty_avg
assert_equal 0, Stats::TimeToComplete.new([]).avg
end
def test_empty_min_sec
assert_equal '00:00:00', Stats::TimeToComplete.new([]).min_sec
end
def test_minimum
assert_equal 2.1, Stats::TimeToComplete.new(fake_tasks).min
end
def test_maximum
assert_equal 6.1, Stats::TimeToComplete.new(fake_tasks).max
end
def test_avg
assert_equal 4.1, Stats::TimeToComplete.new(fake_tasks).avg
end
def test_min_sec
assert_equal '2 days 03:04:05', Stats::TimeToComplete.new(fake_tasks).min_sec
end
def test_min_sec_with_less_than_a_day
task = FakeTask.new(day0, now)
assert_equal '03:04:05', Stats::TimeToComplete.new([task]).min_sec
end
def test_rounding
start_time = Time.utc(2012, 12, 31, 8, 0, 0)
task = FakeTask.new(start_time, now)
ttc = Stats::TimeToComplete.new([task])
assert_equal 1.8, ttc.avg
assert_equal 1.8, ttc.min
assert_equal 1.8, ttc.max
end
def test_min_sec_with_almost_three_days
start_time = Time.utc(2012, 12, 30, 8, 0, 0)
task = FakeTask.new(start_time, now)
stats = Stats::TimeToComplete.new([task])
assert_equal 2.8, stats.min
assert_equal '2 days 19:04:05', stats.min_sec
end
end

View file

@ -0,0 +1,123 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
require 'todos_controller'
class TodoCreateParamsHelperTest < ActiveSupport::TestCase
def test_works_with_request_as_root_hash_entry
params = {'request' => { 'todo' => { 'description' => 'foo'}}}
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal({'description' => 'foo'}, params_helper.attributes)
end
def test_works_with_todo_as_root_hash_entry
params = { 'todo' => { 'description' => 'foo'}}
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal({'description' => 'foo'}, params_helper.attributes)
end
def test_show_from_accessor
expected_date = Time.now
params = { 'todo' => { 'show_from' => expected_date}}
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal(expected_date, params_helper.show_from)
end
def test_due_accessor
expected_date = Time.now
params = { 'todo' => { 'due' => expected_date}}
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal(expected_date, params_helper.due)
end
def test_tag_list_accessor
params = { 'todo' => { }, 'tag_list' => 'foo, bar'}
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal('foo, bar', params_helper.tag_list)
end
def test_parse_dates_parses_show_from_date_based_on_prefs
params = { 'todo' => { 'show_from' => '20/05/07', 'due' => '23/5/07'}}
user = users(:admin_user)
prefs = user.prefs
prefs.date_format = "%d/%m/%y" # make sure the format matches the above
params_helper = Todos::TodoCreateParamsHelper.new(params, user)
params_helper.parse_dates()
assert_equal Date.new(2007, 5, 20), params_helper.show_from.to_date
end
def test_parse_dates_parses_due_date_based_on_prefs
params = { 'todo' => { 'show_from' => '20/5/07', 'due' => '23/5/07'}}
user = users(:admin_user)
prefs = user.prefs
prefs.date_format = "%d/%m/%y" # make sure the format matches the above
params_helper = Todos::TodoCreateParamsHelper.new(params, user)
params_helper.parse_dates()
assert_equal Date.new(2007, 5, 23), params_helper.due.to_date
end
def test_parse_dates_sets_due_to_empty_string_if_nil
params = { 'todo' => { 'show_from' => '20/5/07', 'due' => nil}}
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
params_helper.parse_dates()
assert_equal '', params_helper.due
end
def test_project_name_is_stripped_of_leading_and_trailing_whitespace
params = { 'project_name' => ' Visit New Orleans ' }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal 'Visit New Orleans', params_helper.project_name
end
def test_project_name_is_nil_when_unspecified
params = { }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_nil params_helper.project_name
end
def test_context_name_is_stripped_of_leading_and_trailing_whitespace
params = { 'context_name' => ' mobile phone ' }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal 'mobile phone', params_helper.context_name
end
def test_context_name_is_nil_when_unspecified
params = { }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_nil params_helper.context_name
end
def test_project_specified_by_name_is_false_when_project_id_is_specified
params = { 'todo' => { 'project_id' => 2 } }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal false, params_helper.project_specified_by_name?
end
def test_project_specified_by_name_is_false_when_project_name_is_blank
params = { 'project_name' => nil, 'todo' => {} }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal false, params_helper.project_specified_by_name?
end
def test_project_specified_by_name_is_false_when_project_name_is_none
params = { 'project_name' => 'None', 'todo' => {} }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal false, params_helper.project_specified_by_name?
end
def test_context_specified_by_name_is_false_when_context_id_is_specified
params = { 'todo' => { 'context_id' => 3 } }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal false, params_helper.context_specified_by_name?
end
def test_context_specified_by_name_is_false_when_context_name_is_blank
params = { 'context_name' => nil, 'todo' => {} }
params_helper = Todos::TodoCreateParamsHelper.new(params, users(:admin_user))
assert_equal false, params_helper.context_specified_by_name?
end
end

471
test/models/todo_test.rb Normal file
View file

@ -0,0 +1,471 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class TodoTest < ActiveSupport::TestCase
fixtures :todos, :recurring_todos, :users, :contexts, :preferences, :tags, :taggings, :projects
def setup
@not_completed1 = Todo.find(1).reload
@not_completed2 = Todo.find(2).reload
@completed = Todo.find(8).reload
end
# Test loading a todo item
def test_load
assert_kind_of Todo, @not_completed1
assert_equal 1, @not_completed1.id
assert_equal 1, @not_completed1.context_id
assert_equal 2, @not_completed1.project_id
assert_equal "Call Bill Gates to find out how much he makes per day", @not_completed1.description
assert_nil @not_completed1.notes
assert @not_completed1.completed? == false
assert_equal 1.week.ago.beginning_of_day.strftime("%Y-%m-%d %H:%M"), @not_completed1.created_at.strftime("%Y-%m-%d %H:%M")
assert_equal 2.week.from_now.beginning_of_day.strftime("%Y-%m-%d"), @not_completed1.due.strftime("%Y-%m-%d")
assert_nil @not_completed1.completed_at
assert_equal 1, @not_completed1.user_id
end
def test_completed
assert_kind_of Todo, @completed
assert @completed.completed?
assert_not_nil @completed.completed_at
end
def test_completed_at_cleared_after_toggle_to_active
assert_kind_of Todo, @completed
assert @completed.completed?
@completed.toggle_completion!
assert @completed.active?
assert_nil @completed.completed_at
end
# Validation tests
#
def test_validate_presence_of_description
assert_equal "Call dinosaur exterminator", @not_completed2.description
@not_completed2.description = ""
assert !@not_completed2.save
assert_equal 1, @not_completed2.errors.count
assert_equal "can't be blank", @not_completed2.errors[:description][0]
end
def test_validate_length_of_description
assert_equal "Call dinosaur exterminator", @not_completed2.description
@not_completed2.description = generate_random_string(101)
assert !@not_completed2.save
assert_equal 1, @not_completed2.errors.count
assert_equal "is too long (maximum is 100 characters)", @not_completed2.errors[:description][0]
end
def test_validate_length_of_notes
assert_equal "Ask him if I need to hire a skip for the corpses.", @not_completed2.notes
@not_completed2.notes = generate_random_string(60001)
assert !@not_completed2.save
assert_equal 1, @not_completed2.errors.count
assert_equal "is too long (maximum is 60000 characters)", @not_completed2.errors[:notes][0]
end
def test_validate_show_from_must_be_a_date_in_the_future
t = @not_completed2
t.show_from = 1.week.ago
assert !t.save, "todo should not be saved without validation errors"
assert_equal 1, t.errors.count
assert_equal "must be a date in the future", t.errors[:show_from][0]
end
def test_validate_circular_dependencies
@completed.activate!
@not_completed3=@completed
# 2 -> 1
@not_completed1.add_predecessor(@not_completed2)
assert @not_completed1.save!
assert_equal 1, @not_completed2.successors.count
# 3 -> 2 -> 1
@not_completed2.add_predecessor(@not_completed3)
assert @not_completed2.save!
assert_equal 1, @not_completed3.successors.count
# 1 -> 3 -> 2 -> 1 == circle
@not_completed3.add_predecessor(@not_completed1)
assert !@not_completed3.valid?
error_msg = "Adding ''Call Bill Gates to find out how much he makes per day' <'agenda'; 'Make more money than Billy Gates'>' would create a circular dependency"
assert_equal error_msg, @not_completed3.errors["Depends on:"][0]
end
def test_defer_an_existing_todo
@not_completed2
assert_equal :active, @not_completed2.aasm_current_state
@not_completed2.show_from = Time.zone.now + 1.week
assert @not_completed2.save, "should have saved successfully" + @not_completed2.errors.to_xml
assert_equal :deferred, @not_completed2.aasm_current_state
end
def test_create_a_new_deferred_todo
user = users(:other_user)
todo = user.todos.build
todo.show_from = next_week
todo.context_id = 1
todo.description = 'foo'
assert todo.save, "should have saved successfully" + todo.errors.to_xml
assert_equal :deferred, todo.aasm_current_state
end
def test_create_a_new_deferred_todo_by_passing_attributes
user = users(:other_user)
todo = user.todos.build(:show_from => next_week, :context_id => 1, :description => 'foo')
assert todo.save, "should have saved successfully" + todo.errors.to_xml
assert_equal :deferred, todo.aasm_current_state
end
def test_toggle_completion
t = @not_completed1
assert_equal :active, t.aasm_current_state
t.toggle_completion!
assert_equal :completed, t.aasm_current_state
t.toggle_completion!
assert_equal :active, t.aasm_current_state
end
def test_toggle_completion_with_show_from_in_future
t = @not_completed1
t.show_from= 1.week.from_now
t.save!
assert_equal :deferred, t.aasm_current_state
t.toggle_completion!
assert_equal :completed, t.aasm_current_state
end
def test_toggle_completion_with_show_from_in_past
t = @not_completed1
t.update_attribute(:show_from, 1.week.ago)
assert_equal :active, t.aasm_current_state
assert t.toggle_completion!, "shoud be able to mark active todo complete even if show_from is set in the past"
assert_equal :completed, t.aasm_current_state
end
def test_activate_also_saves
t = @not_completed1
t.show_from = 1.week.from_now
t.save!
assert t.deferred?
t.reload
t.activate!
assert t.active?
t.reload
assert t.active?
end
def test_activate_also_clears_show_from
# setup test case
t = @not_completed1
t.show_from = 1.week.from_now
t.save!
assert t.deferred?
t.reload
# activate and check show_from
t.activate!
assert t.active?
assert t.show_from.nil?
end
def test_clearing_show_from_activates_todo
t = @not_completed1
t.show_from = 1.week.from_now
t.save!
t.reload
assert t.deferred?
t.show_from = nil
t.save!
t.reload
assert t.active?
end
def test_project_returns_null_object_when_nil
t = @not_completed1
assert !t.project.is_a?(NullProject)
t.project = nil
assert t.project.is_a?(NullProject)
end
def test_initial_state_defaults_to_active
t = Todo.new
t.description = 'foo'
t.context_id = 1
t.save!
t.reload
assert_equal :active, t.aasm_current_state
end
def test_initial_state_is_deferred_when_show_from_in_future
t = Todo.new
t.user = users(:admin_user)
t.description = 'foo'
t.context_id = 1
t.show_from = 1.week.from_now.to_date
t.save!
t.reload
assert_equal :deferred, t.aasm_current_state
end
def test_todo_is_not_starred
assert !@not_completed1.starred?
end
def test_todo_2_is_not_starred
assert !Todo.find(2).starred?
end
def test_todo_is_starred_after_starred_tag_is_added
@not_completed1._add_tags('starred')
assert @not_completed1.starred?
end
def test_todo_is_starred_after_toggle_starred
@not_completed1.toggle_star!
assert @not_completed1.starred?
end
def test_todo_is_not_starred_after_toggle_starred_twice
@not_completed1.toggle_star!
@not_completed1.toggle_star!
assert !@not_completed1.starred?
end
def test_todo_specification_handles_null_project
# @not_completed1 has a project
todo_desc = @not_completed1.description
assert_equal "'#{todo_desc}' <'agenda'; 'Make more money than Billy Gates'>", @not_completed1.specification
# now check on null
@not_completed1.project = nil
@not_completed1.save
assert_equal "'#{todo_desc}' <'agenda'; '(none)'>", @not_completed1.specification
end
def test_add_predecessor_list
todo = Todo.new
single = @not_completed1.id.to_s
multi = single + ", " + @not_completed2.id.to_s # note one space after comma
@predecessor_array = todo.add_predecessor_list(single)
assert_not_nil @predecessor_array
assert_equal 1, @predecessor_array.size
@predecessor_array = todo.add_predecessor_list(multi)
assert_not_nil @predecessor_array
assert_equal 2, @predecessor_array.size
end
def test_add_predecessor_list_with_comma
# test for #975
todo = Todo.new
@not_completed1.description = "test,1,2,3"
@not_completed1.save
@not_completed2.description = "test,4,5,6"
@not_completed2.save
single = @not_completed1.id.to_s
multi = single + "," + @not_completed2.id.to_s # note no space after comma
@predecessor_array = todo.add_predecessor_list(single)
assert_not_nil @predecessor_array
assert_equal 1, @predecessor_array.size
@predecessor_array = todo.add_predecessor_list(multi)
assert_not_nil @predecessor_array
assert_equal 2, @predecessor_array.size
end
def test_add_and_remove_precesessor
@not_completed1.add_predecessor(@not_completed2)
@not_completed1.save_predecessors
# blocking is not done automagically
@not_completed1.block!
assert @not_completed1.uncompleted_predecessors?
assert @not_completed1.pending?, "a todo with predecessors should be pending"
@not_completed1.remove_predecessor(@not_completed2)
@not_completed1.save_predecessors
assert !@not_completed1.uncompleted_predecessors?
assert @not_completed1.active?, "removing last predecessor should activate todo"
end
def test_finding_todos_with_a_tag
todo = @not_completed1
todo.tag_list = "a, b, c"
todo.save!
tag_a = Tag.where(:name => "a").first
tag_b = Tag.where(:name => "b").first
tag_c = Tag.where(:name => "c").first
todos_with_a = Todo.with_tag(tag_a)
assert_equal 1, todos_with_a.count
assert_equal todo.description, todos_with_a.first.description
todos_with_b = Todo.with_tag(tag_b)
assert_equal 1, todos_with_b.count
assert_equal todo.id, todos_with_b.first.id
todo2 = @not_completed2
todo2.tag_list = "a, c, d"
todo2.save!
tag_d = Tag.where(:name => "d").first
todos_with_a = Todo.with_tag(tag_a)
assert_equal 2, todos_with_a.count
todos_with_d = Todo.with_tag(tag_d)
assert_equal 1, todos_with_d.count
end
def test_finding_todos_with_more_tags_using_OR
todo1 = @not_completed1
todo1.tag_list = "a, b, c"
todo1.save!
todo2 = @not_completed2
todo2.tag_list = "a, c, d"
todo2.save!
tag_a = Tag.where(:name => "a").first
tag_b = Tag.where(:name => "b").first
tag_c = Tag.where(:name => "c").first
tag_d = Tag.where(:name => "d").first
# overlapping tags
tag_ids = [tag_a.id, tag_c.id]
todos_with_a_or_c = Todo.with_tags(tag_ids)
assert_equal 2, todos_with_a_or_c.count
# non-overlapping tags
tag_ids = [tag_b.id, tag_d.id]
todos_with_b_or_d = Todo.with_tags(tag_ids)
assert_equal 2, todos_with_b_or_d.count
end
def test_finding_todos_with_more_tags_using_AND
todo1 = @not_completed1
todo1.tag_list = "a, b, c"
todo1.save!
todo2 = @not_completed2
todo2.tag_list = "a, c, d"
todo2.save!
tag_a_id = Tag.where(:name => "a").first.id
tag_b_id = Tag.where(:name => "b").first.id
todos_with_a_and_b = Todo.with_tags([tag_a_id]).with_tags([tag_b_id])
assert_equal 1, todos_with_a_and_b.count
assert_equal todo1.id, todos_with_a_and_b.first.id
end
def test_finding_todos_with_more_tags_using_AND_and_OR
todo1 = @not_completed1
todo1.tag_list = "a, b, c"
todo1.save!
todo2 = @not_completed2
todo2.tag_list = "a, c, d"
todo2.save!
tag_a_id = Tag.where(:name => "a").first.id
tag_b_id = Tag.where(:name => "b").first.id
tag_c_id = Tag.where(:name => "c").first.id
todos_with_aORc_and_b = Todo.with_tags([tag_a_id, tag_c_id]).with_tags([tag_b_id])
assert_equal 1, todos_with_aORc_and_b.count
assert_equal todo1.id, todos_with_aORc_and_b.first.id
# let todo2 fit the expression
todo2.tag_list = "a, b, r"
todo2.save!
todos_with_aORc_and_b = Todo.with_tags([tag_a_id, tag_c_id]).with_tags([tag_b_id])
assert_equal 2, todos_with_aORc_and_b.count
end
# test named_scopes
def test_find_completed
# Given 2 completed todos, one completed now and one completed 2 months ago
@not_completed1.toggle_completion!
@completed.completed_at = 2.months.ago
@completed.save!
completed_old = @completed
completed_now = @not_completed1
# When I use the finders
recent_completed_todos = Todo.completed_after(1.month.ago)
older_completed_todos = Todo.completed_before(1.month.ago)
# Then completed1 should be before and completed2 should be after a month ago
assert older_completed_todos.include?(completed_old)
assert recent_completed_todos.include?(completed_now)
# And completed1 should not be after and completed2 should not be before a month ago
assert !older_completed_todos.include?(completed_now)
assert !recent_completed_todos.include?(completed_old)
end
def test_find_created
# Given 2 created todos, one created now and one created 2 months ago
user = @completed.user
todo_old = user.todos.create!({:description => "created long long ago", :context => @completed.context})
todo_old.created_at = 2.months.ago
todo_old.save!
todo_now = user.todos.create!({:description => "just created", :context => @completed.context})
# When I use the finders
recent_created_todos = Todo.created_after(1.month.ago)
older_created_todos = Todo.created_before(1.month.ago)
# Then todo1 should be before and todo2 should be after a month ago
assert older_created_todos.include?(todo_old)
assert recent_created_todos.include?(todo_now)
# And todo1 should not be after and todo2 should not be before a month ago
assert !older_created_todos.include?(todo_now)
assert !recent_created_todos.include?(todo_old)
end
def test_notes_are_rendered_on_save
user = @completed.user
todo = user.todos.create(:description => "test", :context => @completed.context)
assert_nil todo.notes
assert_nil todo.rendered_notes
todo.notes = "*test*"
todo.save!
todo.reload
assert_equal "*test*", todo.notes
assert_equal "<p><strong>test</strong></p>", todo.rendered_notes
end
def test_from_rich_message_adds_to_default_context
user = @completed.user
default_context_id = @completed.context_id
new_todo = Todo::from_rich_message(user, default_context_id, "new todo", "notes")
assert_not_nil new_todo
assert_equal "new todo", new_todo.description
assert_equal "notes", new_todo.notes
assert_equal default_context_id, new_todo.context_id
end
end

396
test/models/user_test.rb Normal file
View file

@ -0,0 +1,396 @@
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
class UserTest < ActiveSupport::TestCase
fixtures :users, :preferences, :projects, :contexts, :todos, :recurring_todos
def setup
assert_equal "test", ENV['RAILS_ENV']
assert_equal "change-me", Tracks::Config.salt
@admin_user = User.find(1)
@other_user = User.find(2)
end
# Test an admin user model
#
def test_admin
assert_kind_of User, @admin_user
assert_equal 1, @admin_user.id
assert_equal "admin", @admin_user.login
assert_not_nil @admin_user.crypted_password
assert_not_nil @admin_user.token
assert @admin_user.is_admin
end
# Test a non-admin user model
def test_non_admin
assert_kind_of User, @other_user
assert_equal 2, @other_user.id
assert_equal "jane", @other_user.login
assert_not_nil @other_user.crypted_password
assert_not_nil @other_user.token
assert @other_user.is_admin == false || @other_user.is_admin == 0
end
# ============================================
# Validations
# ============================================
# Test a password shorter than 5 characters
#
def test_validate_short_password
assert_no_difference 'User.count' do
u = create_user :password => generate_random_string(4)
assert_equal "is too short (minimum is 5 characters)", u.errors[:password][0]
end
end
def test_validate_long_password
assert_no_difference 'User.count' do
u = create_user :password => generate_random_string(41)
assert_equal "is too long (maximum is 40 characters)", u.errors[:password][0]
end
end
def test_validate_correct_length_password
assert_difference 'User.count' do
create_user :password => generate_random_string(6)
end
end
def test_validate_missing_password
assert_no_difference 'User.count' do
u = create_user :password => ''
assert_equal ["can't be blank", "is too short (minimum is 5 characters)"], u.errors[:password]
end
end
def test_validate_short_login
assert_no_difference 'User.count' do
u = create_user :login => 'ba'
assert_equal "is too short (minimum is 3 characters)", u.errors[:login][0]
end
end
def test_validate_long_login
assert_no_difference 'User.count' do
u = create_user :login => generate_random_string(81)
assert_equal "is too long (maximum is 80 characters)", u.errors[:login][0]
end
end
def test_validate_correct_length_login
assert_difference 'User.count' do
create_user :login => generate_random_string(6)
end
end
def test_validate_missing_login
assert_no_difference 'User.count' do
u = create_user :login => ''
assert_equal ["can't be blank", "is too short (minimum is 3 characters)"], u.errors[:login]
end
end
def test_display_name_with_first_and_last_name_set
@other_user.first_name = "Jane"
@other_user.last_name = "Doe"
assert_equal "Jane Doe", @other_user.display_name
end
def test_display_name_with_first_name_set
@other_user.first_name = "Jane"
@other_user.last_name = nil
assert_equal "Jane", @other_user.display_name
end
def test_display_name_with_last_name_set
@other_user.first_name = nil
@other_user.last_name = "Doe"
assert_equal "Doe", @other_user.display_name
end
def test_display_name_with_neither_first_nor_last_name_set
@other_user.first_name = nil
@other_user.last_name = nil
assert_equal @other_user.login, @other_user.display_name
end
def test_prefs_is_short_for_preference
assert_equal @admin_user.preference, @admin_user.prefs
end
def test_to_param_returns_login
assert_equal @admin_user.login, @admin_user.to_param
end
def test_change_password
assert_not_nil User.authenticate(@admin_user.login, "abracadabra")
@admin_user.change_password("foobar", "foobar")
@admin_user.reload
assert_nil User.authenticate(@admin_user.login, "abracadabra")
assert_not_nil User.authenticate(@admin_user.login, "foobar")
end
def test_projects_next_project
moremoney = projects(:moremoney)
next_project = @admin_user.projects.next_from(moremoney)
assert_equal projects(:gardenclean), next_project
end
def test_projects_previous_project
moremoney = projects(:moremoney)
previous_project = @admin_user.projects.previous_from(moremoney)
assert_equal projects(:timemachine), previous_project
end
def test_projects_next_project_nil
gardenclean = projects(:gardenclean)
next_project = @admin_user.projects.next_from(gardenclean)
assert_nil next_project
end
def test_projects_previous_project_nil
timemachine = projects(:timemachine)
previous_project = @admin_user.projects.previous_from(timemachine)
assert_nil previous_project
end
def test_no_users_yet
assert !User.no_users_yet?
User.delete_all
assert User.no_users_yet?
end
def test_generate_token_updates_token
assert_value_changed @admin_user, :token do
@admin_user.send :generate_token
end
end
def test_find_admin
assert_equal @admin_user, User.find_admin
end
def test_validates_auth_type
@other_user.auth_type = 'dnacheck'
assert !@other_user.save
assert_equal 1, @other_user.errors.count
assert_equal ["not a valid authentication type (dnacheck)"], @other_user.errors[:auth_type]
end
def test_find_context_by_params
u = @admin_user
c = u.contexts.find_by_params('id' => '1')
assert_equal contexts(:agenda), c
c = u.contexts.find_by_params('context_id' => '1')
assert_equal contexts(:agenda), c
end
def test_find_project_by_params
u = @admin_user
p = u.projects.find_by_params('id' => '1')
assert_equal projects(:timemachine), p
p = u.projects.find_by_params('project_id' => '1')
assert_equal projects(:timemachine), p
end
def test_update_project_positions
assert_equal 1, Project.find(1).position
assert_equal 2, Project.find(2).position
assert_equal 3, Project.find(3).position
@admin_user.projects.update_positions([2,1,3])
assert_equal 2, Project.find(1).position
assert_equal 1, Project.find(2).position
assert_equal 3, Project.find(3).position
end
def test_find_and_activate_deferred_todos_that_are_ready
assert_equal 1, @admin_user.deferred_todos.count
@admin_user.deferred_todos[0].show_from = Time.now.utc - 5.seconds
@admin_user.deferred_todos[0].save
@admin_user.deferred_todos.reload
@admin_user.deferred_todos.find_and_activate_ready
@admin_user.deferred_todos.reload
assert_equal 0, @admin_user.deferred_todos.count
end
def test_sort_active_projects_alphabetically
u = users(:admin_user)
u.projects.alphabetize(:state => "active")
assert_equal 1, projects(:timemachine).position
assert_equal 2, projects(:gardenclean).position
assert_equal 3, projects(:moremoney).position
end
def test_sort_active_projects_alphabetically_case_insensitive
u = users(:admin_user)
projects(:timemachine).name = projects(:timemachine).name.downcase
projects(:timemachine).save!
u.projects.alphabetize(:state => "active")
assert_equal 1, projects(:timemachine).position
assert_equal 2, projects(:gardenclean).position
assert_equal 3, projects(:moremoney).position
end
def test_should_create_user
assert_difference 'User.count' do
user = create_user
assert !user.new_record?, "#{user.errors.full_messages.to_sentence}"
end
end
def test_should_require_login
assert_no_difference 'User.count' do
u = create_user(:login => nil)
assert u.errors[:login][0]
end
end
def test_should_require_password
assert_no_difference 'User.count' do
u = create_user(:password => nil)
assert u.errors[:password][0]
end
end
def test_should_require_password_confirmation
assert_no_difference 'User.count' do
u = create_user(:password_confirmation => nil)
assert u.errors[:password_confirmation][0]
end
end
def test_should_reset_password
users(:other_user).update_attributes(:password => 'new password', :password_confirmation => 'new password')
assert_equal users(:other_user), User.authenticate('jane', 'new password')
end
def test_should_not_rehash_password
users(:other_user).update_attributes(:login => 'jane2')
assert_equal users(:other_user), User.authenticate('jane2', 'sesame')
end
def test_should_authenticate_user
assert_equal users(:other_user), User.authenticate('jane', 'sesame')
end
def test_should_set_remember_token
users(:other_user).remember_me
assert_not_nil users(:other_user).remember_token
assert_not_nil users(:other_user).remember_token_expires_at
end
def test_should_unset_remember_token
users(:other_user).remember_me
assert_not_nil users(:other_user).remember_token
users(:other_user).forget_me
assert_nil users(:other_user).remember_token
end
def test_should_discover_using_depracted_password
assert_nil @admin_user.uses_deprecated_password?
assert_nil @other_user.uses_deprecated_password?
assert users(:user_with_sha1_password).uses_deprecated_password?
end
def test_should_not_have_deprecated_password_after_update
u = users(:user_with_sha1_password)
assert u.uses_deprecated_password?
u.change_password("foobar", "foobar")
assert_nil u.uses_deprecated_password?
end
def test_should_authenticate_with_deprecated_password
assert_nil User.authenticate('mr_deprecated', 'wrong password')
assert_equal users(:user_with_sha1_password),
User.authenticate('mr_deprecated', 'foobar')
end
def test_password_matches
assert_not_nil User.authenticate(@admin_user.login, "abracadabra")
assert_nil User.authenticate(@admin_user.login, "incorrect")
assert_not_nil User.authenticate(users(:user_with_sha1_password).login, "foobar")
assert_nil User.authenticate(users(:user_with_sha1_password).login, "wrong")
end
def test_update_positions_of_contexts
u = users(:admin_user)
assert_equal "1,2,3,4,5,6,7,8,9,12", u.contexts.map(&:id).join(",")
u.contexts.update_positions [1,2,3,8,9,12,4,5,6,7]
assert_equal "1,2,3,8,9,12,4,5,6,7", u.contexts.reload.map(&:id).join(",")
end
def test_cache_notes_count_for_projects
u = users(:admin_user)
u.projects.each do |p|
assert_nil p.cached_note_count, "notes count should not be there"
end
u.projects.cache_note_counts
u.projects.each do |p|
assert !p.cached_note_count.nil?, "notes count should be there"
end
end
def test_actionize_projects
u = users(:admin_user)
assert_equal "1,2,3", u.projects.map(&:id).join(",")
u.projects.actionize
assert_equal "3,2,1", u.projects.reload.map(&:id).join(",")
end
def test_remember_token
u = users(:admin_user)
assert_nil u.remember_token
assert_nil u.remember_token_expires_at
# set token on 2013-feb-28
Timecop.travel(Time.local(2013, 2, 28)) do
u.remember_me
assert_not_nil u.remember_token_expires_at
assert u.remember_token?
end
# token should be valid after 5 days
Timecop.travel(Time.local(2013, 3, 5)) do
assert u.remember_token?
end
# token should not be valid after more than 2 weeks
Timecop.travel(Time.local(2013, 3, 28)) do
assert !u.remember_token?
end
end
def test_count_todos_by_group
u = users(:admin_user)
# test group counts for projects and contexts
project_counts = u.todos.count_by_group(:project_id)
assert_equal "6,3,4,4", project_counts.map{|pc|pc[1]}.join(",")
context_counts = u.todos.count_by_group(:context_id)
assert_equal "7,3,1,3,1,2", context_counts.map{|cc|cc[1]}.join(",")
# add a todo to the first context and check that the count is increased
u.todos.create!(:description => "yet another todo", :context => u.contexts.first)
context_counts = u.todos.reload.count_by_group(:context_id)
assert_equal "8,3,1,3,1,2", context_counts.map{|cc|cc[1]}.join(",")
end
protected
def create_user(options = {})
options[:password_confirmation] = options[:password] unless options.has_key?(:password_confirmation) || !options.has_key?(:password)
User.create({ :login => 'quire', :password => 'quire', :password_confirmation => 'quire' }.merge(options))
end
end