diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 4fd7697e..db0aed76 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -29,7 +29,7 @@ module ApplicationHelper
end
def days_from_today(date)
- (date.in_time_zone.to_date - current_user.time.to_date).to_i
+ (date.in_time_zone.to_date - UserTime.new(current_user).date).to_i
end
# Check due date in comparison to today's date Flag up date appropriately with
diff --git a/app/models/preference.rb b/app/models/preference.rb
index afe2b69f..e0150cd8 100644
--- a/app/models/preference.rb
+++ b/app/models/preference.rb
@@ -1,7 +1,7 @@
class Preference < ActiveRecord::Base
belongs_to :user
belongs_to :sms_context, :class_name => 'Context'
-
+
def self.due_styles
{ :due_in_n_days => 0, :due_on => 1}
end
@@ -22,6 +22,6 @@ class Preference < ActiveRecord::Base
raise ArgumentError.new("Bad argument type:#{s.class}")
end
- user.at_midnight(date)
+ UserTime.new(user).midnight(date)
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 46d369ff..cd106fd4 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -99,9 +99,10 @@ class Project < ActiveRecord::Base
end
end
- def needs_review?(current_user)
+ def needs_review?(user)
+ current_time = UserTime.new(user).time
return active? && ( last_reviewed.nil? ||
- (last_reviewed < current_user.time - current_user.prefs.review_period.days))
+ (last_reviewed < current_time - user.prefs.review_period.days))
end
def blocked?
@@ -134,7 +135,7 @@ class Project < ActiveRecord::Base
end
def age_in_days
- @age_in_days ||= (Date.today - created_at.to_date + 1).to_i
+ @age_in_days ||= ((Time.now.utc - created_at).to_i / 1.day) + 1
end
def self.import(params, user)
diff --git a/app/models/todo.rb b/app/models/todo.rb
index d6ed1fa8..95669c03 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -263,7 +263,7 @@ class Todo < ActiveRecord::Base
activate
else
# parse Date objects into the proper timezone
- date = user.at_midnight(date) if (date.is_a? Date)
+ date = UserTime.new(user).midnight(date) if (date.is_a? Date)
# show_from needs to be set before state_change because of "bug" in aasm.
# If show_from is not set, the todo will not validate and thus aasm will not save
diff --git a/app/models/user.rb b/app/models/user.rb
index 5aa94f8a..87726741 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -159,16 +159,8 @@ class User < ActiveRecord::Base
save!
end
- def time
- Time.now.in_time_zone(prefs.time_zone)
- end
-
def date
- time.midnight
- end
-
- def at_midnight(date)
- return ActiveSupport::TimeZone[prefs.time_zone].local(date.year, date.month, date.day, 0, 0, 0)
+ UserTime.new(self).midnight(Time.now)
end
def generate_token
diff --git a/app/views/recurring_todos/_recurring_todo_form.html.erb b/app/views/recurring_todos/_recurring_todo_form.html.erb
index 644571f5..2ad9ac63 100644
--- a/app/views/recurring_todos/_recurring_todo_form.html.erb
+++ b/app/views/recurring_todos/_recurring_todo_form.html.erb
@@ -30,7 +30,7 @@
<%= t('todos.recurrence.starts_on') %>: <%=
- text_field(:recurring_todo, :start_from, "value" => format_date(current_user.time), "size" => 12, "class" => "Date", "autocomplete" => "off") %>
+ text_field(:recurring_todo, :start_from, "value" => format_date(UserTime.new(current_user).time), "size" => 12, "class" => "Date", "autocomplete" => "off") %>
<%= t('todos.recurrence.ends_on') %>:
<%= radio_button_tag('recurring_todo[ends_on]', 'no_end_date', true)%> <%= t('todos.recurrence.no_end_date') %>
diff --git a/app/views/todos/_edit_form.m.erb b/app/views/todos/_edit_form.m.erb
index 83e90d23..c7fb5a59 100644
--- a/app/views/todos/_edit_form.m.erb
+++ b/app/views/todos/_edit_form.m.erb
@@ -3,7 +3,7 @@
<%= get_list_of_error_messages_for(@todo) if @todo %>
-<% this_year = current_user.time.to_date.strftime("%Y").to_i -%>
+<% this_year = UserTime.new(current_user).date.strftime("%Y").to_i -%>
<%= t('common.description') %>
<%= text_field( "todo", "description", "tabindex" => 1, "maxlength" => 100, "size" => 50) %>
<%= t('todos.tags') %>
diff --git a/features/step_definitions/project_steps.rb b/features/step_definitions/project_steps.rb
index 3cbd1b52..43b782df 100644
--- a/features/step_definitions/project_steps.rb
+++ b/features/step_definitions/project_steps.rb
@@ -5,7 +5,7 @@ end
Given /^I have an outdated project "([^"]*)" with (\d+) todos$/ do |project_name, num_todos|
step "I have a project \"#{project_name}\" with #{num_todos} todos"
@project = @current_user.projects.where(:name => project_name).first
- @project.last_reviewed = @current_user.time - @current_user.prefs.review_period.days-1
+ @project.last_reviewed = UserTime.new(@current_user).time - @current_user.prefs.review_period.days-1
@project.save
end
diff --git a/features/step_definitions/todo_create_steps.rb b/features/step_definitions/todo_create_steps.rb
index d98172e0..cf782492 100644
--- a/features/step_definitions/todo_create_steps.rb
+++ b/features/step_definitions/todo_create_steps.rb
@@ -79,7 +79,7 @@ end
Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)" that is due next week$/ do |action_description, project_name, tags, context_name|
step "I have a todo with description \"#{action_description}\" in project \"#{project_name}\" with tags \"#{tags}\" in the context \"#{context_name}\""
- @todo.due = @current_user.time + 1.week
+ @todo.due = UserTime.new(@current_user).time + 1.week
@todo.save!
end
@@ -94,7 +94,7 @@ Given /^I have ([0-9]+) deferred todos$/ do |count|
context = @current_user.contexts.create!(:name => "context B")
count.to_i.downto 1 do |i|
todo = @current_user.todos.create!(:context_id => context.id, :description => "todo #{i}")
- todo.show_from = @current_user.time + 1.week
+ todo.show_from = UserTime.new(@current_user).time + 1.week
todo.save!
end
end
@@ -102,7 +102,7 @@ end
Given /^I have a deferred todo "([^"]*)" in the context "([^"]*)"$/ do |description, context_name|
context = @current_user.contexts.where(:name => context_name).first_or_create
todo = @current_user.todos.create!(:context_id => context.id, :description => description)
- todo.show_from = @current_user.time + 1.week
+ todo.show_from = UserTime.new(@current_user).time + 1.week
todo.save!
end
@@ -112,13 +112,13 @@ end
Given /^I have a deferred todo "([^"]*)" in context "([^"]*)" with tags "([^"]*)"$/ do |action_description, context_name, tag_list|
step "I have a todo \"#{action_description}\" in context \"#{context_name}\" with tags \"#{tag_list}\""
- @todo.show_from = @current_user.time + 1.week
+ @todo.show_from = UserTime.new(@current_user).time + 1.week
@todo.save!
end
Given(/^I have a deferred todo "(.*?)" in the context "(.*?)" in the project "(.*?)"$/) do |action_description, context_name, project_name|
step "I have a todo \"#{action_description}\" in the context \"#{context_name}\" in the project \"#{project_name}\""
- @todo.show_from = @current_user.time + 1.week
+ @todo.show_from = UserTime.new(@current_user).time + 1.week
@todo.save!
end
@@ -293,7 +293,7 @@ end
When(/^I submit a new deferred action with description "([^"]*)"$/) do |description|
fill_in "todo[description]", :with => description
- fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week)
+ fill_in "todo[show_from]", :with => format_date(UserTime.new(@current_user).time + 1.week)
submit_next_action_form
end
@@ -305,7 +305,7 @@ When /^I submit a new deferred action with description "([^"]*)" and the tags "(
fill_in "todo_context_name", :with => context_name
fill_in "tag_list", :with => tags
- fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week)
+ fill_in "todo[show_from]", :with => format_date(UserTime.new(@current_user).time + 1.week)
end
submit_next_action_form
end
@@ -315,7 +315,7 @@ When(/^I submit a new deferred action with description "([^"]*)" to project "(.*
fill_in "todo[description]", :with => description
fill_in "todo_project_name", :with => project_name
fill_in "tag_list", :with => tags
- fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week)
+ fill_in "todo[show_from]", :with => format_date(UserTime.new(@current_user).time + 1.week)
end
submit_next_action_form
end
@@ -330,7 +330,7 @@ When /^I submit a new deferred action with description "([^"]*)" to project "([^
fill_in "todo_project_name", :with => project_name
fill_in "todo_context_name", :with => context_name
fill_in "tag_list", :with => tags
- fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week)
+ fill_in "todo[show_from]", :with => format_date(UserTime.new(@current_user).time + 1.week)
end
submit_next_action_form
diff --git a/features/support/tracks_login_helper.rb b/features/support/tracks_login_helper.rb
index cc97b18a..7599e447 100644
--- a/features/support/tracks_login_helper.rb
+++ b/features/support/tracks_login_helper.rb
@@ -32,8 +32,8 @@ module TracksLoginHelper
Rails.application.routes_reloader.paths.each{ |path| load(path) }
_routes.draw do
# here you can add any route you want
- match "/test_login_backdoor", to: "session_backdoor#create"
- match "login/expire_session", to: "session_backdoor#expire_session"
+ get "/test_login_backdoor", to: "session_backdoor#create"
+ get "login/expire_session", to: "session_backdoor#expire_session"
end
ActiveSupport.on_load(:action_controller) { _routes.finalize! }
ensure
diff --git a/lib/staleness.rb b/lib/staleness.rb
index 51144007..d5375621 100644
--- a/lib/staleness.rb
+++ b/lib/staleness.rb
@@ -4,12 +4,12 @@ class Staleness
SECONDS_PER_DAY = 86400
def self.days_stale(item, current_user)
return 0 if cannot_be_stale(item, current_user)
- (current_user.time - item.created_at).to_i / SECONDS_PER_DAY
+ (UserTime.new(current_user).time - item.created_at).to_i / SECONDS_PER_DAY
end
def self.cannot_be_stale(item, current_user)
return true if item.due || item.completed?
- return true if item.created_at > current_user.time
+ return true if item.created_at > UserTime.new(current_user).time
false
end
end
diff --git a/lib/user_time.rb b/lib/user_time.rb
new file mode 100644
index 00000000..9a565f47
--- /dev/null
+++ b/lib/user_time.rb
@@ -0,0 +1,22 @@
+require 'active_support/values/time_zone'
+
+class UserTime
+ attr_reader :user, :timezone
+
+ def initialize(user)
+ @user = user
+ @timezone = ActiveSupport::TimeZone[user.prefs.time_zone]
+ end
+
+ def midnight(date)
+ timezone.local(date.year, date.month, date.day, 0, 0, 0)
+ end
+
+ def time
+ timezone.now
+ end
+
+ def date
+ time.to_date
+ end
+end
diff --git a/test/controllers/recurring_todos_controller_test.rb b/test/controllers/recurring_todos_controller_test.rb
index 54baacf1..d9e91395 100644
--- a/test/controllers/recurring_todos_controller_test.rb
+++ b/test/controllers/recurring_todos_controller_test.rb
@@ -117,7 +117,9 @@ class RecurringTodosControllerTest < ActionController::TestCase
new_todo = Todo.where(:recurring_todo_id => 5).first
# due date should be the target_date
- assert_equal users(:admin_user).at_midnight(Date.new(target_date.year, target_date.month, target_date.day)), new_todo.due
+ user = users(:admin_user)
+ target_date = Date.new(target_date.year, target_date.month, target_date.day)
+ assert_equal UserTime.new(user).midnight(target_date), new_todo.due
# show_from should be nil since now+4.days-10.days is in the past
assert_equal nil, new_todo.show_from
diff --git a/test/models/preference_test.rb b/test/models/preference_test.rb
index 4080cb62..9a66cfb5 100644
--- a/test/models/preference_test.rb
+++ b/test/models/preference_test.rb
@@ -13,16 +13,17 @@ class PreferenceTest < ActiveSupport::TestCase
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
+ date = Time.new(2007, 05, 20).in_time_zone(@admin_user.preference.time_zone).at_midnight
+ assert_equal date.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
diff --git a/test/models/project_test.rb b/test/models/project_test.rb
index e5e3f716..47ba1a5f 100644
--- a/test/models/project_test.rb
+++ b/test/models/project_test.rb
@@ -84,12 +84,12 @@ class ProjectTest < ActiveSupport::TestCase
def test_review_project
assert_nil @timemachine.last_reviewed
- assert @timemachine.needs_review?(nil)
+ assert @timemachine.needs_review?(users(:admin_user))
end
def test_review_completedprojects
@timemachine.complete!
- assert !@timemachine.needs_review?(nil)
+ assert !@timemachine.needs_review?(users(:admin_user))
end
def test_complete_project
diff --git a/test/models/staleness_test.rb b/test/models/staleness_test.rb
index 553371b1..c2c3efc4 100644
--- a/test/models/staleness_test.rb
+++ b/test/models/staleness_test.rb
@@ -3,11 +3,18 @@ require_relative '../../lib/staleness'
class StalenessTest < Test::Unit::TestCase
- FakeUser = Struct.new(:time)
+ FakePrefs = Struct.new(:time_zone)
+ FakeUser = Struct.new(:time) do
+ def prefs
+ @prefs ||= FakePrefs.new("UTC")
+ end
+ end
+
FakeTask = Struct.new(:due, :completed, :created_at) do
def completed?
self.completed
end
+
end
def now
@@ -28,6 +35,11 @@ class StalenessTest < Test::Unit::TestCase
def setup
@current_user = FakeUser.new(now)
+ Timecop.freeze(Time.local(2013,02,28))
+ end
+
+ def teardown
+ Timecop.return
end
def test_item_with_due_date_is_not_stale_ever
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 2ac18294..895b68a1 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -3,7 +3,7 @@ require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
# set config for tests. Overwrite those read from config/site.yml. Use inject to avoid warning about changing CONSTANT
-{"salt" => "change-me", "authentication_schemes" => ["database"], "prefered_auth" => "database"}.inject( SITE_CONFIG ) { |h, elem| h[elem[0]] = elem[1]; h }
+{ "salt" => "change-me", "authentication_schemes" => ["database"], "prefered_auth" => "database"}.inject( SITE_CONFIG ) { |h, elem| h[elem[0]] = elem[1]; h }
class ActiveSupport::TestCase
ActiveRecord::Migration.check_pending!