diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb index fed1dc3a..9aa3b83e 100644 --- a/app/controllers/login_controller.rb +++ b/app/controllers/login_controller.rb @@ -1,7 +1,6 @@ class LoginController < ApplicationController layout 'login' - filter_parameter_logging :user_password skip_before_filter :set_session_expiration skip_before_filter :login_required before_filter :login_optional diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 77a9984a..f14ef68f 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,5 +1,5 @@ class UsersController < ApplicationController - filter_parameter_logging "password" + before_filter :admin_login_required, :only => [ :index, :show, :destroy ] skip_before_filter :login_required, :only => [ :new, :create ] skip_before_filter :check_for_deprecated_password_hash, diff --git a/app/models/context.rb b/app/models/context.rb index ee97a134..35adab3e 100644 --- a/app/models/context.rb +++ b/app/models/context.rb @@ -9,15 +9,12 @@ class Context < ActiveRecord::Base scope :hidden, :conditions => { :hide => true } acts_as_list :scope => :user, :top_of_list => 0 - # extend NamePartFinder - # include Tracks::TodoList attr_protected :user validates_presence_of :name, :message => "context must have a name" validates_length_of :name, :maximum => 255, :message => "context name must be less than 256 characters" validates_uniqueness_of :name, :message => "already exists", :scope => "user_id" -# validates_does_not_contain :name, :string => ',', :message => "cannot contain the comma (',') character" def self.feed_options(user) # TODO: move to view or helper diff --git a/app/models/message_gateway.rb b/app/models/message_gateway.rb index af67a782..69a924b8 100644 --- a/app/models/message_gateway.rb +++ b/app/models/message_gateway.rb @@ -1,8 +1,9 @@ class MessageGateway < ActionMailer::Base - include ActionView::Helpers::SanitizeHelper - extend ActionView::Helpers::SanitizeHelper::ClassMethods + # include ActionView::Helpers::SanitizeHelper + # extend ActionView::Helpers::SanitizeHelper::ClassMethods def receive(email) + puts "email = #{email}" address = '' if SITE_CONFIG['email_dispatch'] == 'to' address = email.to[0] @@ -10,9 +11,9 @@ class MessageGateway < ActionMailer::Base address = email.from[0] end - user = User.find(:first, :include => [:preference], :conditions => ["preferences.sms_email = ?", address.strip]) + user = User.where("preferences.sms_email" => address.strip).first(:include => [:preference]) if user.nil? - user = User.find(:first, :include => [:preference], :conditions => ["preferences.sms_email = ?", address.strip[1,100]]) + user = User.where("preferences.sms_email" => address.strip[1.100]).first(:include => [:preference]) end return if user.nil? context = user.prefs.sms_context @@ -25,7 +26,7 @@ class MessageGateway < ActionMailer::Base body_part = email.parts.find{|m| m.content_type == "text/plain"} notes = sanitize body_part.body.strip else - if email.subject.empty? + if email.subject && email.subject.blank? description = sanitize email.body.strip notes = nil else @@ -35,7 +36,7 @@ class MessageGateway < ActionMailer::Base end # stupid T-Mobile often sends the same message multiple times - return if user.todos.find(:first, :conditions => {:description => description}) + return if user.todos.where(:description => description).first todo = Todo.from_rich_message(user, context.id, description, notes) todo.save! diff --git a/app/models/tag.rb b/app/models/tag.rb index bb39407a..92bdaa20 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -11,6 +11,10 @@ class Tag < ActiveRecord::Base validates_presence_of :name validates_uniqueness_of :name, :case_sensitive => false + attr_accessible :name + + before_create :before_create + # Callback to strip extra spaces from the tagname before saving it. If you # allow tags to be renamed later, you might want to use the # before_save callback instead. diff --git a/app/models/tagging.rb b/app/models/tagging.rb index 46291f6a..95e14516 100644 --- a/app/models/tagging.rb +++ b/app/models/tagging.rb @@ -2,12 +2,18 @@ # The Tagging join model. class Tagging < ActiveRecord::Base + + attr_accessible :taggable_id, :tag belongs_to :tag belongs_to :taggable, :polymorphic => true + + after_destroy :after_destroy + + private # This callback makes sure that an orphaned Tag is deleted if it no longer tags anything. def after_destroy - tag.destroy_without_callbacks if tag and tag.taggings.count == 0 + tag.destroy if tag and tag.taggings.count == 0 end end diff --git a/app/models/todo.rb b/app/models/todo.rb index 75f1fef4..ea2297ea 100644 --- a/app/models/todo.rb +++ b/app/models/todo.rb @@ -104,7 +104,23 @@ class Todo < ActiveRecord::Base validates_length_of :notes, :maximum => 60000, :allow_nil => true validates_presence_of :show_from, :if => :deferred? validates_presence_of :context + validate :check_show_from_in_future + validate :check_circular_dependencies + def check_show_from_in_future + if !show_from.blank? && show_from < user.date + errors.add("show_from", I18n.t('models.todo.error_date_must_be_future')) + end + end + + def check_circular_dependencies + unless @predecessor_array.nil? # Only validate predecessors if they changed + @predecessor_array.each do |todo| + errors.add("Depends on:", "Adding '#{todo.specification}' would create a circular dependency") if is_successor?(todo) + end + end + end + def initialize(*args) super(*args) @predecessor_array = nil # Used for deferred save of predecessors @@ -121,7 +137,7 @@ class Todo < ActiveRecord::Base end def uncompleted_predecessors? - return !uncompleted_predecessors.all(true).empty? + return !uncompleted_predecessors.all.empty? end # Returns a string with description @@ -130,17 +146,6 @@ class Todo < ActiveRecord::Base return "\'#{self.description}\' <\'#{self.context.title}\'; \'#{project_name}\'>" end - def validate - if !show_from.blank? && show_from < user.date - errors.add("show_from", I18n.t('models.todo.error_date_must_be_future')) - end - unless @predecessor_array.nil? # Only validate predecessors if they changed - @predecessor_array.each do |todo| - errors.add("Depends on:", "Adding '#{h(todo.specification)}' would create a circular dependency") if is_successor?(todo) - end - end - end - def save_predecessors unless @predecessor_array.nil? # Only save predecessors if they changed current_array = self.predecessors diff --git a/app/models/user.rb b/app/models/user.rb index 2dcaf367..4db04e0a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -9,9 +9,9 @@ class User < ActiveRecord::Base has_many :contexts, :order => 'position ASC', :dependent => :delete_all do - # def find_by_params(params) - # find(params['id'] || params['context_id']) || nil - # end + def find_by_params(params) + find(params['id'] || params['context_id']) || nil + end def update_positions(context_ids) context_ids.each_with_index {|id, position| context = self.detect { |c| c.id == id.to_i } @@ -23,9 +23,9 @@ class User < ActiveRecord::Base has_many :projects, :order => 'projects.position ASC', :dependent => :delete_all do - # def find_by_params(params) - # find(params['id'] || params['project_id']) - # end + def find_by_params(params) + find(params['id'] || params['project_id']) + end def update_positions(project_ids) project_ids.each_with_index {|id, position| project = self.detect { |p| p.id == id.to_i } @@ -100,17 +100,16 @@ class User < ActiveRecord::Base validates_confirmation_of :password validates_length_of :login, :within => 3..80 validates_uniqueness_of :login, :on => :create - # validates_presence_of :open_id_url, :if => :using_openid? + validate :validate_auth_type before_create :crypt_password, :generate_token before_update :crypt_password - # before_save :normalize_open_id_url #for will_paginate plugin cattr_accessor :per_page @@per_page = 5 - def validate + def validate_auth_type unless Tracks::Config.auth_schemes.include?(auth_type) errors.add("auth_type", "not a valid authentication type (#{auth_type})") end @@ -137,25 +136,15 @@ class User < ActiveRecord::Base return candidate if candidate.auth_type.eql?("cas") end - if Tracks::Config.auth_schemes.include?('open_id') - # hope the user enters the correct data - return candidate if candidate.auth_type.eql?("open_id") - end - return nil end - # def self.find_by_open_id_url(raw_identity_url) - # normalized_open_id_url = OpenIdAuthentication.normalize_identifier(raw_identity_url) - # find(:first, :conditions => ['open_id_url = ?', normalized_open_id_url]) - # end - def self.no_users_yet? count == 0 end def self.find_admin - find(:first, :conditions => [ "is_admin = ?", true ]) + where(:is_admin => true).first end def to_param @@ -230,37 +219,22 @@ class User < ActiveRecord::Base end def sha1(s) - Digest::SHA1.hexdigest salted s + Digest::SHA1.hexdigest(salted(s)) end - def hash(s) - BCrypt::Password.create s + def create_hash(s) + BCrypt::Password.create(s) end protected def crypt_password return if password.blank? - write_attribute("crypted_password", hash(password)) if password == password_confirmation + write_attribute("crypted_password", self.create_hash(password)) if password == password_confirmation end def password_required? auth_type == 'database' && crypted_password.blank? || !password.blank? end - # def using_openid? - # auth_type == 'open_id' - # end - # - # def normalize_open_id_url - # return if open_id_url.nil? - # - # # fixup empty url value - # if open_id_url.empty? - # self.open_id_url = nil - # return - # end - # - # self.open_id_url = OpenIdAuthentication.normalize_identifier(open_id_url) - # end end diff --git a/config/environment.rb b/config/environment.rb index 8e8e1fdb..6f9bda48 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -2,4 +2,4 @@ require File.expand_path('../application', __FILE__) # Initialize the rails application -Tracksapp::Application.initialize! +Tracksapp::Application.initialize! \ No newline at end of file diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb index 999df201..c948e063 100644 --- a/config/initializers/wrap_parameters.rb +++ b/config/initializers/wrap_parameters.rb @@ -5,7 +5,7 @@ # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. ActiveSupport.on_load(:action_controller) do - wrap_parameters format: [:json] + wrap_parameters(:format => [:json]) end # Disable root element in JSON by default. diff --git a/config/locales/en.yml b/config/locales/en.yml index 429368a5..e23261df 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -136,9 +136,9 @@ en: next: Next todo: todo note: - zero: no notes - one: 1 note - other: %{count} notes + zero: "no notes" + one: "1 note" + other: "%{count} notes" context: Context drag_handle: DRAG description: Description diff --git a/test/unit/message_gateway_test.rb b/test/functional/message_gateway_test.rb similarity index 92% rename from test/unit/message_gateway_test.rb rename to test/functional/message_gateway_test.rb index 7f94cb4e..6e7c3e3e 100644 --- a/test/unit/message_gateway_test.rb +++ b/test/functional/message_gateway_test.rb @@ -9,7 +9,7 @@ class MessageGatewayTest < ActiveSupport::TestCase end def load_message(filename) - MessageGateway.receive(File.read(File.join(RAILS_ROOT, 'test', 'fixtures', filename))) + MessageGateway.receive(File.read(File.join(Rails.root, 'test', 'fixtures', filename))) end def test_sms_with_no_subject @@ -51,14 +51,14 @@ class MessageGatewayTest < ActiveSupport::TestCase def test_no_user todo_count = Todo.count - badmessage = File.read(File.join(RAILS_ROOT, 'test', 'fixtures', 'sample_sms.txt')) + badmessage = File.read(File.join(Rails.root, 'test', 'fixtures', 'sample_sms.txt')) badmessage.gsub!("5555555555", "notauser") MessageGateway.receive(badmessage) assert_equal(todo_count, Todo.count) end def test_direct_to_context - message = File.read(File.join(RAILS_ROOT, 'test', 'fixtures', 'sample_sms.txt')) + message = File.read(File.join(Rails.root, 'test', 'fixtures', 'sample_sms.txt')) valid_context_msg = message.gsub('message_content', 'this is a task @ anothercontext') invalid_context_msg = message.gsub('message_content', 'this is also a task @ notacontext') diff --git a/test/test_helper.rb b/test/test_helper.rb index 8bf1192f..75ec7e1c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -11,3 +11,46 @@ class ActiveSupport::TestCase # Add more helper methods to be used by all tests here... end + +module Tracks + class Config + def self.salt + "change-me" + end + def self.auth_schemes + return ["database","open_id"] + end + end +end + +class ActiveSupport::TestCase + + # Generates a random string of ascii characters (a-z, "1 0") + # of a given length for testing assignment to fields + # for validation purposes + # + def generate_random_string(length) + string = "" + characters = %w(a b c d e f g h i j k l m n o p q r s t u v w z y z 1\ 0) + length.times do + pick = characters[rand(26)] + string << pick + end + return string + end + + def assert_equal_dmy(date1, date2) + assert_equal date1.strftime("%d-%m-%y"), date2.strftime("%d-%m-%y") + end + +end + +class Test::Unit::TestCase + + def assert_value_changed(object, method = nil) + initial_value = object.send(method) + yield + assert_not_equal initial_value, object.send(method), "#{object}##{method}" + end + +end diff --git a/test/unit/context_test.rb b/test/unit/context_test.rb index 644bf63c..dc5f2559 100644 --- a/test/unit/context_test.rb +++ b/test/unit/context_test.rb @@ -9,18 +9,23 @@ class ContextTest < ActiveSupport::TestCase @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.on(:name) + assert_equal "context must have a name", @agenda.errors[:name][0] end def test_validate_name_is_less_than_256 - @agenda.name = "a"*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.on(:name) + assert_equal "context name must be less than 256 characters", @agenda.errors[:name][0] end def test_validate_name_is_unique @@ -29,29 +34,9 @@ class ContextTest < ActiveSupport::TestCase newcontext.user_id = contexts(:agenda).user_id assert !newcontext.save assert_equal 1, newcontext.errors.count - assert_equal "already exists", newcontext.errors.on(:name) + assert_equal "already exists", newcontext.errors[:name][0] end - - def test_validate_name_does_not_contain_comma - newcontext = Context.new - newcontext.name = "phone,telegraph" - assert !newcontext.save - assert_equal 1, newcontext.errors.count - assert_equal "cannot contain the comma (',') character", newcontext.errors.on(:name) - end - - def test_find_by_namepart_with_exact_match - c = Context.find_by_namepart('agenda') - assert_not_nil c - assert_equal @agenda.id, c.id - end - - def test_find_by_namepart_with_starts_with - c = Context.find_by_namepart('agen') - assert_not_nil c - assert_equal @agenda.id, c.id - end - + def test_delete_context_deletes_todos_within_it assert_equal 7, @agenda.todos.count agenda_todo_ids = @agenda.todos.collect{|t| t.id } @@ -60,23 +45,7 @@ class ContextTest < ActiveSupport::TestCase assert !Todo.exists?(todo_id) end end - - def test_not_done_todos - assert_equal 6, @agenda.not_done_todos.size - t = @agenda.not_done_todos[0] - t.complete! - t.save! - assert_equal 5, Context.find(@agenda.id).not_done_todos.size - end - - def test_done_todos - assert_equal 1, @agenda.done_todos.size - t = @agenda.not_done_todos[0] - t.complete! - t.save! - assert_equal 2, Context.find(@agenda.id).done_todos.size - end - + def test_to_param_returns_id assert_equal '1', @agenda.to_param end diff --git a/test/unit/project_test.rb b/test/unit/project_test.rb index 51179b31..b8570b16 100644 --- a/test/unit/project_test.rb +++ b/test/unit/project_test.rb @@ -8,18 +8,32 @@ class ProjectTest < ActiveSupport::TestCase @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.on(:name) + assert_equal "project must have a name", @timemachine.errors[:name][0] end def test_validate_name_is_less_than_256 - @timemachine.name = "a"*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.on(:name) + assert_equal "project name must be less than 256 characters", @timemachine.errors[:name][0] end def test_validate_name_is_unique @@ -28,29 +42,10 @@ class ProjectTest < ActiveSupport::TestCase newproj.user_id = projects(:timemachine).user_id assert !newproj.save assert_equal 1, newproj.errors.count - assert_equal "already exists", newproj.errors.on(:name) - end - - def test_validate_name_can_contain_comma - newproj = Project.new - newproj.name = "Buy iPhones for Luke,bsag,David Allen" - assert newproj.save - assert_equal 0, newproj.errors.count - assert_equal "Buy iPhones for Luke,bsag,David Allen", newproj.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 + 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 @@ -69,6 +64,24 @@ class ProjectTest < ActiveSupport::TestCase 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) @@ -88,43 +101,15 @@ class ProjectTest < ActiveSupport::TestCase assert_in_delta Time.now, @timemachine.completed_at, 1 end - def test_find_project_by_namepart_with_exact_match - p = Project.find_by_namepart('Build a working time machine') - assert_not_nil p - assert_equal @timemachine.id, p.id - end - - def test_find_project_by_namepart_with_starts_with - p = Project.find_by_namepart('Build a') - assert_not_nil p - assert_equal @timemachine.id, p.id - 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) + assert !Todo.exists?(t_id) end end - def test_not_done_todos - assert_equal 3, @timemachine.todos.not_completed.size - t = @timemachine.todos.not_completed[0] - t.complete! - t.save! - assert_equal 2, Project.find(@timemachine.id).todos.not_completed.size - end - - def test_done_todos - assert_equal 0, @timemachine.todos.completed.size - t = @timemachine.todos.not_completed[0] - t.complete! - t.save! - assert_equal 1, Project.find(@timemachine.id).todos.completed.size - end - def test_deferred_todos assert_equal 1, @timemachine.todos.deferred.size t = @timemachine.todos.not_completed[0] @@ -149,29 +134,26 @@ class ProjectTest < ActiveSupport::TestCase assert_equal 'Tracks Projects', opts[:title], 'Unexpected value for :title key of feed_options' assert_equal 'Lists all the projects for Admin Schmadmin', opts[:description], 'Unexpected value for :description key of feed_options' 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 + + 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_transition_to_same_state - assert_equal :active, @timemachine.aasm_current_state - @timemachine.transition_to(:active) - assert_equal :active, @timemachine.aasm_current_state - 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 = next_week + first_todo.show_from = Time.zone.now + 1.week assert_equal :deferred, @moremoney.todos[0].aasm_current_state assert_equal 1, @moremoney.todos.deferred.count @@ -191,11 +173,4 @@ class ProjectTest < ActiveSupport::TestCase assert_equal 3, @moremoney.todos.not_completed.count end - def test_default_context_name - p = Project.new - assert_equal '', p.default_context.name - p.default_context = contexts(:agenda) - assert_equal 'agenda', p.default_context.name - end - end diff --git a/test/unit/recurring_todo_test.rb b/test/unit/recurring_todo_test.rb index b82bc59e..e01c86c7 100644 --- a/test/unit/recurring_todo_test.rb +++ b/test/unit/recurring_todo_test.rb @@ -1,18 +1,17 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper') class RecurringTodoTest < ActiveSupport::TestCase - fixtures :todos, :users, :contexts, :preferences, :tags, :taggings, :recurring_todos def setup - @every_day = RecurringTodo.find(1).reload - @every_workday = RecurringTodo.find(2).reload - @weekly_every_day = RecurringTodo.find(3).reload - @monthly_every_last_friday = RecurringTodo.find(4).reload - @yearly = RecurringTodo.find(5).reload + @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) + @monthly_every_last_friday = recurring_todos(:check_with_bill_every_last_friday_of_month) + @yearly = recurring_todos(:birthday_reinier) @today = Time.now.utc @tomorrow = @today + 1.day - @in_three_days = Time.now.utc + 3.days + @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) @@ -34,8 +33,8 @@ class RecurringTodoTest < ActiveSupport::TestCase 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 strftime in compare, because milisec / secs could be different - assert_equal @today.strftime("%d-%m-%y"), due_date.strftime("%d-%m-%y") + # 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) @@ -44,13 +43,13 @@ class RecurringTodoTest < ActiveSupport::TestCase # 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 + 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 @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 @@ -63,7 +62,7 @@ class RecurringTodoTest < ActiveSupport::TestCase assert_equal nil, @every_day.get_due_date(@today-3.days) # check show from get the next day - assert_equal @today, @every_day.get_show_from_date(@today-1.days) + 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' @@ -73,7 +72,7 @@ class RecurringTodoTest < ActiveSupport::TestCase @every_day.show_always = false @every_day.show_from_delta=10 - assert_equal @today, @every_day.get_show_from_date(@today+9.days) #today+1+9-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 @@ -140,9 +139,9 @@ class RecurringTodoTest < ActiveSupport::TestCase @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 + assert_equal @wednesday, due_date due_date = @weekly_every_day.get_due_date(@wednesday) - assert_equal @tuesday+1.week, due_date + assert_equal @tuesday+1.week, due_date @weekly_every_day.every_day = ' s' due_date = @weekly_every_day.get_due_date(@sunday) @@ -180,7 +179,7 @@ class RecurringTodoTest < ActiveSupport::TestCase 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 + assert_equal @sunday, due_date # june 8th # same month, previous date due_date = @yearly.get_due_date(@saturday) # june 7th @@ -195,7 +194,7 @@ class RecurringTodoTest < ActiveSupport::TestCase 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.recurrence_selector = 1 @yearly.every_other3 = 2 # second @yearly.every_count = 3 # wednesday # beginning of same year @@ -213,7 +212,7 @@ class RecurringTodoTest < ActiveSupport::TestCase # test handling of nil as previous # # start_from is way_back - due_date1 = @yearly.get_due_date(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 @@ -250,7 +249,7 @@ class RecurringTodoTest < ActiveSupport::TestCase # 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 + 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) @@ -270,7 +269,7 @@ class RecurringTodoTest < ActiveSupport::TestCase this_year = Time.now.utc.year @yearly.start_from = Time.zone.local(this_year+1,6,12) - due_date = @yearly.get_due_date(nil) + due_date = @yearly.get_due_date(nil) assert_equal due_date.year, this_year+2 end @@ -308,7 +307,7 @@ class RecurringTodoTest < ActiveSupport::TestCase @every_day.inc_occurences assert_equal true, @every_day.has_next_todo(@in_three_days) @every_day.inc_occurences - assert_equal false, @every_day.has_next_todo(@in_three_days) + assert_equal false, @every_day.has_next_todo(@in_three_days) # after completion, when you reactivate the recurring todo, the occurences # count should be reset diff --git a/test/unit/todo_create_params_helper_test.rb b/test/unit/todo_create_params_helper_test.rb index 4aecff69..7b981b88 100644 --- a/test/unit/todo_create_params_helper_test.rb +++ b/test/unit/todo_create_params_helper_test.rb @@ -5,14 +5,14 @@ class TodoCreateParamsHelperTest < ActiveSupport::TestCase def test_works_with_request_as_root_hash_entry params = {'request' => { 'todo' => { 'description' => 'foo'}}} - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal({'description' => 'foo'}, params_helper.attributes) end def test_works_with_todo_as_root_hash_entry params = { 'todo' => { 'description' => 'foo'}} - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal({'description' => 'foo'}, params_helper.attributes) end @@ -20,7 +20,7 @@ class TodoCreateParamsHelperTest < ActiveSupport::TestCase def test_show_from_accessor expected_date = Time.now params = { 'todo' => { 'show_from' => expected_date}} - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal(expected_date, params_helper.show_from) end @@ -28,43 +28,43 @@ class TodoCreateParamsHelperTest < ActiveSupport::TestCase def test_due_accessor expected_date = Time.now params = { 'todo' => { 'due' => expected_date}} - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal(expected_date, params_helper.due) end def test_tag_list_accessor params = { 'todo' => { }, 'todo_tag_list' => 'foo, bar'} - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal('foo, bar', params_helper.tag_list) end def test_parse_dates_parses_show_from_date_based_on_prefs - params = { 'todo' => { 'show_from' => '5/20/07', 'due' => '5/23/07'}} - prefs = flexmock() - prefs.should_receive(:parse_date).with('5/20/07').and_return(Date.new(2007, 5, 20)) - prefs.should_receive(:parse_date).with('5/23/07').and_return(Date.new(2007, 5, 23)) + params = { 'todo' => { 'show_from' => '20/05/07', 'due' => '23/5/07'}} + + prefs = users(:admin_user).prefs + prefs.date_format = "%d/%m/%y" # make sure the format matches the above + params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) params_helper.parse_dates() - assert_equal Date.new(2007, 5, 20), params_helper.show_from + 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' => '5/20/07', 'due' => '5/23/07'}} - prefs = flexmock() - prefs.should_receive(:parse_date).with('5/20/07').and_return(Date.new(2007, 5, 20)) - prefs.should_receive(:parse_date).with('5/23/07').and_return(Date.new(2007, 5, 23)) + params = { 'todo' => { 'show_from' => '20/5/07', 'due' => '23/5/07'}} + + prefs = users(:admin_user).prefs + prefs.date_format = "%d/%m/%y" # make sure the format matches the above + params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) params_helper.parse_dates() - assert_equal Date.new(2007, 5, 23), params_helper.due + 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' => '5/20/07', 'due' => nil}} - prefs = flexmock() - prefs.should_receive(:parse_date).with('5/20/07').and_return(Date.new(2007, 5, 20)) - prefs.should_receive(:parse_date).with(nil).and_return(nil) + params = { 'todo' => { 'show_from' => '20/5/07', 'due' => nil}} + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) params_helper.parse_dates() assert_equal '', params_helper.due @@ -72,63 +72,63 @@ class TodoCreateParamsHelperTest < ActiveSupport::TestCase def test_project_name_is_stripped_of_leading_and_trailing_whitespace params = { 'project_name' => ' Visit New Orleans ' } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal 'Visit New Orleans', params_helper.project_name end def test_project_name_is_nil_when_unspecified params = { } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_nil params_helper.project_name end def test_context_name_is_stripped_of_leading_and_trailing_whitespace params = { 'context_name' => ' mobile phone ' } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal 'mobile phone', params_helper.context_name end def test_context_name_is_nil_when_unspecified params = { } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) 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 } } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) 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' => {} } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) 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' => {} } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) 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 } } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) 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' => {} } - prefs = flexmock() + prefs = users(:admin_user).prefs params_helper = TodosController::TodoCreateParamsHelper.new(params, prefs) assert_equal false, params_helper.context_specified_by_name? end diff --git a/test/unit/todo_test.rb b/test/unit/todo_test.rb index bfd8116a..cedaaeb7 100644 --- a/test/unit/todo_test.rb +++ b/test/unit/todo_test.rb @@ -47,7 +47,7 @@ class TodoTest < ActiveSupport::TestCase @not_completed2.description = "" assert !@not_completed2.save assert_equal 1, @not_completed2.errors.count - assert_equal "can't be blank", @not_completed2.errors.on(:description) + assert_equal "can't be blank", @not_completed2.errors[:description][0] end def test_validate_length_of_description @@ -55,7 +55,7 @@ class TodoTest < ActiveSupport::TestCase @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.on(:description) + assert_equal "is too long (maximum is 100 characters)", @not_completed2.errors[:description][0] end def test_validate_length_of_notes @@ -63,7 +63,7 @@ class TodoTest < ActiveSupport::TestCase @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.on(:notes) + 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 @@ -72,20 +72,34 @@ class TodoTest < ActiveSupport::TestCase # and actual show_from value appropriately based on the date assert !t.save assert_equal 1, t.errors.count - assert_equal "must be a date in the future", t.errors.on(:show_from) + assert_equal "must be a date in the future", t.errors[:show_from][0] end - - def test_validate_description_can_contain_quote - t = @not_completed2 - t[:description] = "much \"ado\" about nothing" - assert t.save - assert_equal 0, t.errors.count + + 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 = next_week + @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 diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 247ce2c0..d5ab917e 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -28,7 +28,7 @@ class UserTest < ActiveSupport::TestCase end # Test an admin user model - # + # def test_admin assert_kind_of User, @admin_user assert_equal 1, @admin_user.id @@ -57,14 +57,14 @@ class UserTest < ActiveSupport::TestCase def test_validate_short_password assert_no_difference 'User.count' do u = create_user :password => generate_random_string(4) - assert_error_on u, :password, "is too short (minimum is 5 characters)" + 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_error_on u, :password, "is too long (maximum is 40 characters)" + assert_equal "is too long (maximum is 40 characters)", u.errors[:password][0] end end @@ -77,22 +77,22 @@ class UserTest < ActiveSupport::TestCase def test_validate_missing_password assert_no_difference 'User.count' do u = create_user :password => '' - assert_errors_on u, :password, ["can't be blank", "is too short (minimum is 5 characters)"] + 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_error_on u, :login, "is too short (minimum is 3 characters)" + 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_error_on u, :login, "is too long (maximum is 80 characters)" - end + assert_equal "is too long (maximum is 80 characters)", u.errors[:login][0] + end end def test_validate_correct_length_login @@ -104,7 +104,7 @@ class UserTest < ActiveSupport::TestCase def test_validate_missing_login assert_no_difference 'User.count' do u = create_user :login => '' - assert_errors_on u, :login, ["can't be blank", "is too short (minimum is 3 characters)"] + assert_equal ["can't be blank", "is too short (minimum is 3 characters)"], u.errors[:login] end end @@ -192,7 +192,7 @@ class UserTest < ActiveSupport::TestCase @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.on(:auth_type) + assert_equal ["not a valid authentication type (dnacheck)"], @other_user.errors[:auth_type] end def test_authenticate_can_use_ldap @@ -246,9 +246,9 @@ class UserTest < ActiveSupport::TestCase def test_sort_active_projects_alphabetically u = users(:admin_user) u.projects.alphabetize(:state => "active") - assert_equal 1, projects(:timemachine).position + assert_equal 1, projects(:timemachine).position assert_equal 2, projects(:gardenclean).position - assert_equal 3, projects(:moremoney).position + assert_equal 3, projects(:moremoney).position end def test_sort_active_projects_alphabetically_case_insensitive @@ -256,9 +256,9 @@ class UserTest < ActiveSupport::TestCase projects(:timemachine).name = projects(:timemachine).name.downcase projects(:timemachine).save! u.projects.alphabetize(:state => "active") - assert_equal 1, projects(:timemachine).position + assert_equal 1, projects(:timemachine).position assert_equal 2, projects(:gardenclean).position - assert_equal 3, projects(:moremoney).position + assert_equal 3, projects(:moremoney).position end def test_should_create_user @@ -271,21 +271,21 @@ class UserTest < ActiveSupport::TestCase def test_should_require_login assert_no_difference 'User.count' do u = create_user(:login => nil) - assert u.errors.on(:login) + 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.on(:password) + 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.on(:password_confirmation) + assert u.errors[:password_confirmation][0] end end @@ -316,21 +316,6 @@ class UserTest < ActiveSupport::TestCase assert_nil users(:other_user).remember_token end - def test_normalizes_open_id_url_on_save - ['www.johndoe.com', 'WWW.JOHNDOE.COM', 'http://www.johndoe.com/', 'http://www.johndoe.com'].each do |initial| - assert_open_id_url_normalized_on_save initial, 'http://www.johndoe.com/' - end - end - - def test_normalizes_open_id_url_on_find - u = users(:other_user) - u.open_id_url = 'http://www.johndoe.com' - u.save - ['www.johndoe.com', 'WWW.JOHNDOE.COM', 'http://www.johndoe.com/', 'http://www.johndoe.com'].each do |raw_open_id_url| - assert_equal u.id, User.find_by_open_id_url(raw_open_id_url).id - end - end - def test_should_discover_using_depracted_password assert_nil @admin_user.uses_deprecated_password? assert_nil @other_user.uses_deprecated_password?