mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-25 19:48:48 +01:00
Merge branch 'master' into new-gui
This commit is contained in:
commit
ff1fa62d4d
17 changed files with 299 additions and 254 deletions
|
|
@ -14,64 +14,74 @@ class StatsController < ApplicationController
|
|||
def actions_done_last12months_data
|
||||
# get actions created and completed in the past 12+3 months. +3 for running
|
||||
# average
|
||||
@actions_done_last12months = current_user.todos.completed_after(@cut_off_year).select("completed_at" )
|
||||
@actions_created_last12months = current_user.todos.created_after(@cut_off_year).select("created_at")
|
||||
@actions_done_last12monthsPlus3 = current_user.todos.completed_after(@cut_off_year_plus3).select("completed_at" )
|
||||
@actions_created_last12monthsPlus3 = current_user.todos.created_after(@cut_off_year_plus3).select("created_at")
|
||||
actions_done_last12months = current_user.todos.completed_after(@cut_off_year).select("completed_at" )
|
||||
actions_created_last12months = current_user.todos.created_after(@cut_off_year).select("created_at")
|
||||
|
||||
# convert to array and fill in non-existing months
|
||||
@actions_done_last12months_array = convert_to_months_from_today_array(@actions_done_last12months, 13, :completed_at)
|
||||
@actions_created_last12months_array = convert_to_months_from_today_array(@actions_created_last12months, 13, :created_at)
|
||||
@actions_done_last12monthsPlus3_array = convert_to_months_from_today_array(@actions_done_last12monthsPlus3, 16, :completed_at)
|
||||
@actions_created_last12monthsPlus3_array = convert_to_months_from_today_array(@actions_created_last12monthsPlus3, 16, :created_at)
|
||||
@actions_done_last12months_array = convert_to_months_from_today_array(actions_done_last12months, 13, :completed_at)
|
||||
@actions_created_last12months_array = convert_to_months_from_today_array(actions_created_last12months, 13, :created_at)
|
||||
|
||||
# find max for graph in both arrays
|
||||
@max = [@actions_done_last12months_array.max, @actions_created_last12months_array.max].max
|
||||
|
||||
# find running avg
|
||||
actions_done_last12monthsPlus3 = current_user.todos.completed_after(@cut_off_year_plus3).select("completed_at" )
|
||||
actions_created_last12monthsPlus3 = current_user.todos.created_after(@cut_off_year_plus3).select("created_at")
|
||||
actions_done_last12monthsPlus3_array = convert_to_months_from_today_array(actions_done_last12monthsPlus3, 16, :completed_at)
|
||||
actions_created_last12monthsPlus3_array = convert_to_months_from_today_array(actions_created_last12monthsPlus3, 16, :created_at)
|
||||
|
||||
@actions_done_avg_last12months_array, @actions_created_avg_last12months_array =
|
||||
find_running_avg_array(@actions_done_last12monthsPlus3_array, @actions_created_last12monthsPlus3_array, 13)
|
||||
find_running_avg_array(actions_done_last12monthsPlus3_array, actions_created_last12monthsPlus3_array, 13)
|
||||
|
||||
# interpolate avg for current month.
|
||||
percent_of_month = Time.zone.now.day.to_f / Time.zone.now.end_of_month.day.to_f
|
||||
@interpolated_actions_created_this_month = interpolate_avg(@actions_created_last12months_array, percent_of_month)
|
||||
@interpolated_actions_done_this_month = interpolate_avg(@actions_done_last12months_array, percent_of_month)
|
||||
interpolate_avg_for_current_month(@actions_created_last12months_array, @actions_done_last12months_array)
|
||||
|
||||
@created_count_array = Array.new(13, actions_created_last12months.size/12.0)
|
||||
@done_count_array = Array.new(13, actions_done_last12months.size/12.0)
|
||||
@month_names = Array.new(13){ |i| t('date.month_names')[ (Time.now.mon - i -1 ) % 12 + 1 ]}
|
||||
render :layout => false
|
||||
end
|
||||
|
||||
def interpolate_avg_for_current_month(created_set, done_set)
|
||||
percent_of_month = Time.zone.now.day.to_f / Time.zone.now.end_of_month.day.to_f
|
||||
@interpolated_actions_created_this_month = interpolate_avg(created_set, percent_of_month)
|
||||
@interpolated_actions_done_this_month = interpolate_avg(done_set, percent_of_month)
|
||||
end
|
||||
|
||||
def actions_done_last_years
|
||||
@page_title = t('stats.index_title')
|
||||
@chart = Stats::Chart.new('actions_done_lastyears_data', :height => 400, :width => 900)
|
||||
end
|
||||
|
||||
def actions_done_lastyears_data
|
||||
@actions_done_last_months = current_user.todos.completed.select("completed_at").reorder("completed_at DESC")
|
||||
@actions_created_last_months = current_user.todos.select("created_at").reorder("created_at DESC" )
|
||||
actions_done_last_months = current_user.todos.completed.select("completed_at").reorder("completed_at DESC")
|
||||
actions_created_last_months = current_user.todos.select("created_at").reorder("created_at DESC" )
|
||||
|
||||
# query is sorted, so use last todo to calculate number of months
|
||||
@month_count = [difference_in_months(@today, @actions_created_last_months.last.created_at),
|
||||
difference_in_months(@today, @actions_done_last_months.last.completed_at)].max
|
||||
month_count = [difference_in_months(@today, actions_created_last_months.last.created_at),
|
||||
difference_in_months(@today, actions_done_last_months.last.completed_at)].max
|
||||
|
||||
# convert to array and fill in non-existing months
|
||||
@actions_done_last_months_array = convert_to_months_from_today_array(@actions_done_last_months, @month_count+1, :completed_at)
|
||||
@actions_created_last_months_array = convert_to_months_from_today_array(@actions_created_last_months, @month_count+1, :created_at)
|
||||
@actions_done_last_months_array = convert_to_months_from_today_array(actions_done_last_months, month_count+1, :completed_at)
|
||||
@actions_created_last_months_array = convert_to_months_from_today_array(actions_created_last_months, month_count+1, :created_at)
|
||||
|
||||
# find max for graph in both hashes
|
||||
@max = [@actions_done_last_months_array.max, @actions_created_last_months_array.max].max
|
||||
|
||||
# find running avg
|
||||
@actions_done_avg_last_months_array, @actions_created_avg_last_months_array =
|
||||
find_running_avg_array(@actions_done_last_months_array, @actions_created_last_months_array, @month_count+1)
|
||||
find_running_avg_array(@actions_done_last_months_array, @actions_created_last_months_array, month_count+1)
|
||||
|
||||
# correct last two months since the data of last+1 and last+2 are not available for avg
|
||||
correct_last_two_months(@actions_done_avg_last_months_array, @month_count)
|
||||
correct_last_two_months(@actions_created_avg_last_months_array, @month_count)
|
||||
correct_last_two_months(@actions_done_avg_last_months_array, month_count)
|
||||
correct_last_two_months(@actions_created_avg_last_months_array, month_count)
|
||||
|
||||
# interpolate avg for this month.
|
||||
percent_of_month = Time.zone.now.day.to_f / Time.zone.now.end_of_month.day.to_f
|
||||
@interpolated_actions_created_this_month = interpolate_avg(@actions_created_last_months_array, percent_of_month)
|
||||
@interpolated_actions_done_this_month = interpolate_avg(@actions_done_last_months_array, percent_of_month)
|
||||
interpolate_avg_for_current_month(@actions_created_last_months_array, @actions_done_last_months_array)
|
||||
|
||||
@created_count_array = Array.new(month_count+1, actions_created_last_months.size/month_count)
|
||||
@done_count_array = Array.new(month_count+1, actions_done_last_months.size/month_count)
|
||||
@month_names = Array.new(month_count+1){ |i| t('date.month_names')[ (Time.now.mon - i -1 ) % 12 + 1 ]+ " " + (Time.now - i.months).year.to_s}
|
||||
|
||||
render :layout => false
|
||||
end
|
||||
|
|
@ -449,7 +459,7 @@ class StatsController < ApplicationController
|
|||
end
|
||||
|
||||
def interpolate_avg(set, percent)
|
||||
return (set[0]*(1/percent) + set[1] + set[2]) / 3.0
|
||||
(set[0]*(1/percent) + set[1] + set[2]) / 3.0
|
||||
end
|
||||
|
||||
def correct_last_two_months(month_data, count)
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ module TodosHelper
|
|||
:collapsible => false,
|
||||
:show_empty_containers => true,
|
||||
:container_name => "#{period}",
|
||||
:title =>t("todos.calendar.#{period}", :month => l(Time.zone.now, :format => "%B"))
|
||||
:title =>t("todos.calendar.#{period}", :month => l(Time.zone.now, :format => "%B"), :next_month => l(1.month.from_now, :format => "%B"))
|
||||
}
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ class MessageGateway < ActionMailer::Base
|
|||
end
|
||||
end
|
||||
|
||||
todo = Todo.from_rich_message(user, context.id, description, notes)
|
||||
todo_builder = TodoFromRichMessage.new(user, context.id, description, notes)
|
||||
todo = todo_builder.construct
|
||||
todo.save!
|
||||
Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
|
||||
end
|
||||
|
|
|
|||
7
app/models/null_time.rb
Normal file
7
app/models/null_time.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
class NullTime
|
||||
include Comparable
|
||||
|
||||
def <=>(another)
|
||||
-1 # any other Time object is always greater
|
||||
end
|
||||
end
|
||||
|
|
@ -24,11 +24,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
validates_presence_of :description
|
||||
validates_presence_of :recurring_period
|
||||
validates_presence_of :target
|
||||
validates_presence_of :ends_on
|
||||
validates_presence_of :context
|
||||
validates_presence_of :description, :recurring_period, :target, :ends_on, :context
|
||||
|
||||
validates_length_of :description, :maximum => 100
|
||||
validates_length_of :notes, :maximum => 60000, :allow_nil => true
|
||||
|
|
@ -41,7 +37,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
if %W[daily weekly monthly yearly].include?(recurring_period)
|
||||
self.send("validate_#{recurring_period}")
|
||||
else
|
||||
errors.add(:recurring_period, "is an unknown recurrence pattern: '#{self.recurring_period}'")
|
||||
errors.add(:recurring_period, "is an unknown recurrence pattern: '#{recurring_period}'")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -70,7 +66,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
errors[:base] <<"The nth day of the month may not be empty for recurrence setting" if monthly_every_xth_day.blank?
|
||||
errors[:base] <<"The day of the month may not be empty for recurrence setting" if monthly_day_of_week.blank?
|
||||
else
|
||||
raise Exception.new, "unexpected value of recurrence selector '#{self.recurrence_selector}'"
|
||||
raise Exception.new, "unexpected value of recurrence selector '#{recurrence_selector}'"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -84,13 +80,13 @@ class RecurringTodo < ActiveRecord::Base
|
|||
errors[:base] << "The nth day of the month may not be empty for recurrence setting" if yearly_every_xth_day.blank?
|
||||
errors[:base] << "The day of the week may not be empty for recurrence setting" if yearly_day_of_week.blank?
|
||||
else
|
||||
raise Exception.new, "unexpected value of recurrence selector '#{self.recurrence_selector}'"
|
||||
raise Exception.new, "unexpected value of recurrence selector '#{recurrence_selector}'"
|
||||
end
|
||||
end
|
||||
|
||||
def starts_and_ends_on_validations
|
||||
errors[:base] << "The start date needs to be filled in" if start_from.blank?
|
||||
case self.ends_on
|
||||
case ends_on
|
||||
when 'ends_on_number_of_times'
|
||||
errors[:base] << "The number of recurrences needs to be filled in for 'Ends on'" if number_of_occurences.blank?
|
||||
when "ends_on_end_date"
|
||||
|
|
@ -102,7 +98,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
|
||||
def set_recurrence_on_validations
|
||||
# show always or x days before due date. x not null
|
||||
case self.target
|
||||
case target
|
||||
when 'show_from_date'
|
||||
# no validations
|
||||
when 'due_date'
|
||||
|
|
@ -111,7 +107,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
errors[:base] << "Please fill in the number of days to show the todo before the due date" if show_from_delta.blank?
|
||||
end
|
||||
else
|
||||
raise Exception.new, "unexpected value of recurrence target selector '#{self.recurrence_target}'"
|
||||
raise Exception.new, "unexpected value of recurrence target selector '#{recurrence_target}'"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -142,99 +138,49 @@ class RecurringTodo < ActiveRecord::Base
|
|||
def daily_selector=(selector)
|
||||
case selector
|
||||
when 'daily_every_x_day'
|
||||
self.only_work_days = false
|
||||
only_work_days = false
|
||||
when 'daily_every_work_day'
|
||||
self.only_work_days = true
|
||||
only_work_days = true
|
||||
else
|
||||
raise Exception.new, "unknown daily recurrence pattern: '#{selector}'"
|
||||
end
|
||||
end
|
||||
|
||||
def daily_every_x_days=(x)
|
||||
self.every_other1 = x if recurring_period=='daily'
|
||||
every_other1 = x if recurring_period=='daily'
|
||||
end
|
||||
|
||||
def daily_every_x_days
|
||||
return self.every_other1
|
||||
every_other1
|
||||
end
|
||||
|
||||
# WEEKLY
|
||||
|
||||
def weekly_every_x_week=(x)
|
||||
self.every_other1 = x if recurring_period=='weekly'
|
||||
every_other1 = x if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_every_x_week
|
||||
return self.every_other1
|
||||
every_other1
|
||||
end
|
||||
|
||||
def switch_week_day (day, position)
|
||||
def switch_week_day(day, position)
|
||||
self.every_day = ' ' if self.every_day.nil?
|
||||
self.every_day = self.every_day[0,position] + day + self.every_day[position+1,self.every_day.length]
|
||||
self.every_day = every_day[0, position] + day + every_day[position+1, every_day.length]
|
||||
end
|
||||
|
||||
def weekly_return_monday=(selector)
|
||||
switch_week_day(selector,1) if recurring_period=='weekly'
|
||||
end
|
||||
{ monday: 1, tuesday: 2, wednesday: 3, thursday: 4, friday: 5, saturday: 6, sunday: 0 }.each do |day, number|
|
||||
define_method("weekly_return_#{day}=") do |selector|
|
||||
switch_week_day(selector, number) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_return_tuesday=(selector)
|
||||
switch_week_day(selector,2) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_return_wednesday=(selector)
|
||||
switch_week_day(selector,3) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_return_thursday=(selector)
|
||||
switch_week_day(selector,4) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_return_friday=(selector)
|
||||
switch_week_day(selector,5) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_return_saturday=(selector)
|
||||
switch_week_day(selector,6) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def weekly_return_sunday=(selector)
|
||||
switch_week_day(selector,0) if recurring_period=='weekly'
|
||||
end
|
||||
|
||||
def on_xday(n)
|
||||
unless self.every_day.nil?
|
||||
return self.every_day[n,1] == ' ' ? false : true
|
||||
else
|
||||
return false
|
||||
define_method("on_#{day}") do
|
||||
on_xday number
|
||||
end
|
||||
end
|
||||
|
||||
def on_monday
|
||||
return on_xday(1)
|
||||
end
|
||||
|
||||
def on_tuesday
|
||||
return on_xday(2)
|
||||
end
|
||||
|
||||
def on_wednesday
|
||||
return on_xday(3)
|
||||
end
|
||||
|
||||
def on_thursday
|
||||
return on_xday(4)
|
||||
end
|
||||
|
||||
def on_friday
|
||||
return on_xday(5)
|
||||
end
|
||||
|
||||
def on_saturday
|
||||
return on_xday(6)
|
||||
end
|
||||
|
||||
def on_sunday
|
||||
return on_xday(0)
|
||||
def on_xday(n)
|
||||
every_day && every_day[n, 1] != ' '
|
||||
end
|
||||
|
||||
# MONTHLY
|
||||
|
|
@ -248,17 +194,15 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def monthly_every_x_day
|
||||
return self.every_other1
|
||||
self.every_other1
|
||||
end
|
||||
|
||||
def is_monthly_every_x_day
|
||||
return self.recurrence_selector == 0 if recurring_period == 'monthly'
|
||||
return false
|
||||
recurring_period == 'monthly' && self.recurrence_selector == 0
|
||||
end
|
||||
|
||||
def is_monthly_every_xth_day
|
||||
return self.recurrence_selector == 1 if recurring_period == 'monthly'
|
||||
return false
|
||||
recurring_period == 'monthly' && self.recurrence_selector == 1
|
||||
end
|
||||
|
||||
def monthly_every_x_month=(x)
|
||||
|
|
@ -268,7 +212,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
def monthly_every_x_month
|
||||
# in case monthly pattern is every day x, return every_other2 otherwise
|
||||
# return a default value
|
||||
return self.recurrence_selector == 0 ? self.every_other2 : 1
|
||||
self.recurrence_selector == 0 ? self.every_other2 : 1
|
||||
end
|
||||
|
||||
def monthly_every_x_month2=(x)
|
||||
|
|
@ -278,7 +222,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
def monthly_every_x_month2
|
||||
# in case monthly pattern is every xth day, return every_other2 otherwise
|
||||
# return a default value
|
||||
return self.recurrence_selector == 1 ? self.every_other2 : 1
|
||||
self.recurrence_selector == 1 ? self.every_other2 : 1
|
||||
end
|
||||
|
||||
def monthly_every_xth_day=(x)
|
||||
|
|
@ -286,8 +230,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def monthly_every_xth_day(default=nil)
|
||||
return self.every_other3 unless self.every_other3.nil?
|
||||
return default
|
||||
self.every_other3 || default
|
||||
end
|
||||
|
||||
def monthly_day_of_week=(dow)
|
||||
|
|
@ -295,7 +238,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def monthly_day_of_week
|
||||
return self.every_count
|
||||
self.every_count
|
||||
end
|
||||
|
||||
# YEARLY
|
||||
|
|
@ -311,7 +254,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
def yearly_month_of_year
|
||||
# if recurrence pattern is every x day in a month, return month otherwise
|
||||
# return a default value
|
||||
return self.recurrence_selector == 0 ? self.every_other2 : Time.zone.now.month
|
||||
self.recurrence_selector == 0 ? self.every_other2 : Time.zone.now.month
|
||||
end
|
||||
|
||||
def yearly_month_of_year2=(moy)
|
||||
|
|
@ -321,7 +264,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
def yearly_month_of_year2
|
||||
# if recurrence pattern is every xth day in a month, return month otherwise
|
||||
# return a default value
|
||||
return self.recurrence_selector == 1 ? self.every_other2 : Time.zone.now.month
|
||||
self.recurrence_selector == 1 ? self.every_other2 : Time.zone.now.month
|
||||
end
|
||||
|
||||
def yearly_every_x_day=(x)
|
||||
|
|
@ -329,7 +272,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def yearly_every_x_day
|
||||
return self.every_other1
|
||||
self.every_other1
|
||||
end
|
||||
|
||||
def yearly_every_xth_day=(x)
|
||||
|
|
@ -337,7 +280,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def yearly_every_xth_day
|
||||
return self.every_other3
|
||||
self.every_other3
|
||||
end
|
||||
|
||||
def yearly_day_of_week=(dow)
|
||||
|
|
@ -345,7 +288,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def yearly_day_of_week
|
||||
return self.every_count
|
||||
self.every_count
|
||||
end
|
||||
|
||||
# target
|
||||
|
|
@ -357,9 +300,9 @@ class RecurringTodo < ActiveRecord::Base
|
|||
def recurring_target_as_text
|
||||
case self.target
|
||||
when 'due_date'
|
||||
return I18n.t("todos.recurrence.pattern.due")
|
||||
I18n.t("todos.recurrence.pattern.due")
|
||||
when 'show_from_date'
|
||||
return I18n.t("todos.recurrence.pattern.show")
|
||||
I18n.t("todos.recurrence.pattern.show")
|
||||
else
|
||||
raise Exception.new, "unexpected value of recurrence target '#{self.target}'"
|
||||
end
|
||||
|
|
@ -374,19 +317,20 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def daily_recurrence_pattern
|
||||
return I18n.t("todos.recurrence.pattern.on_work_days") if only_work_days
|
||||
if every_other1 > 1
|
||||
return I18n.t("todos.recurrence.pattern.every_n", :n => every_other1) + " " + I18n.t("common.days_midsentence.other")
|
||||
if only_work_days
|
||||
I18n.t("todos.recurrence.pattern.on_work_days")
|
||||
elsif every_other1 > 1
|
||||
I18n.t("todos.recurrence.pattern.every_n", :n => every_other1) + " " + I18n.t("common.days_midsentence.other")
|
||||
else
|
||||
return I18n.t("todos.recurrence.pattern.every_day")
|
||||
I18n.t("todos.recurrence.pattern.every_day")
|
||||
end
|
||||
end
|
||||
|
||||
def weekly_recurrence_pattern
|
||||
if every_other1 > 1
|
||||
return I18n.t("todos.recurrence.pattern.every_n", :n => every_other1) + " " + I18n.t("common.weeks")
|
||||
I18n.t("todos.recurrence.pattern.every_n", :n => every_other1) + " " + I18n.t("common.weeks")
|
||||
else
|
||||
return I18n.t('todos.recurrence.pattern.weekly')
|
||||
I18n.t('todos.recurrence.pattern.weekly')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -395,27 +339,27 @@ class RecurringTodo < ActiveRecord::Base
|
|||
if self.recurrence_selector == 0
|
||||
on_day = " #{I18n.t('todos.recurrence.pattern.on_day_n', :n => self.every_other1)}"
|
||||
if self.every_other2>1
|
||||
return I18n.t("todos.recurrence.pattern.every_n", :n => self.every_other2) + " " + I18n.t('common.months') + on_day
|
||||
I18n.t("todos.recurrence.pattern.every_n", :n => self.every_other2) + " " + I18n.t('common.months') + on_day
|
||||
else
|
||||
return I18n.t("todos.recurrence.pattern.every_month") + on_day
|
||||
I18n.t("todos.recurrence.pattern.every_month") + on_day
|
||||
end
|
||||
else
|
||||
if self.every_other2>1
|
||||
n_months = "#{self.every_other2} #{I18n.t('common.months')}"
|
||||
else
|
||||
n_months = I18n.t('common.month')
|
||||
end
|
||||
return I18n.t('todos.recurrence.pattern.every_xth_day_of_every_n_months',
|
||||
n_months = if self.every_other2 > 1
|
||||
"#{self.every_other2} #{I18n.t('common.months')}"
|
||||
else
|
||||
I18n.t('common.month')
|
||||
end
|
||||
I18n.t('todos.recurrence.pattern.every_xth_day_of_every_n_months',
|
||||
:x => self.xth, :day => self.day_of_week, :n_months => n_months)
|
||||
end
|
||||
end
|
||||
|
||||
def yearly_recurrence_pattern
|
||||
if self.recurrence_selector == 0
|
||||
return I18n.t("todos.recurrence.pattern.every_year_on",
|
||||
I18n.t("todos.recurrence.pattern.every_year_on",
|
||||
:date => I18n.l(DateTime.new(Time.zone.now.year, self.every_other2, self.every_other1), :format => :month_day))
|
||||
else
|
||||
return I18n.t("todos.recurrence.pattern.every_year_on",
|
||||
I18n.t("todos.recurrence.pattern.every_year_on",
|
||||
:date => I18n.t("todos.recurrence.pattern.the_xth_day_of_month", :x => self.xth, :day => self.day_of_week, :month => self.month_of_year))
|
||||
end
|
||||
end
|
||||
|
|
@ -428,7 +372,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
when 'monthly' then monthly_recurrence_pattern
|
||||
when 'yearly' then yearly_recurrence_pattern
|
||||
else
|
||||
return 'unknown recurrence pattern: period unknown'
|
||||
'unknown recurrence pattern: period unknown'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -436,28 +380,28 @@ class RecurringTodo < ActiveRecord::Base
|
|||
xth_day = [
|
||||
I18n.t('todos.recurrence.pattern.first'),I18n.t('todos.recurrence.pattern.second'),I18n.t('todos.recurrence.pattern.third'),
|
||||
I18n.t('todos.recurrence.pattern.fourth'),I18n.t('todos.recurrence.pattern.last')]
|
||||
return self.every_other3.nil? ? '??' : xth_day[self.every_other3-1]
|
||||
self.every_other3.nil? ? '??' : xth_day[self.every_other3-1]
|
||||
end
|
||||
|
||||
def day_of_week
|
||||
return self.every_count.nil? ? '??' : I18n.t('todos.recurrence.pattern.day_names')[self.every_count]
|
||||
self.every_count.nil? ? '??' : I18n.t('todos.recurrence.pattern.day_names')[self.every_count]
|
||||
end
|
||||
|
||||
def month_of_year
|
||||
return self.every_other2.nil? ? '??' : I18n.t('todos.recurrence.pattern.month_names')[self.every_other2]
|
||||
self.every_other2.nil? ? '??' : I18n.t('todos.recurrence.pattern.month_names')[self.every_other2]
|
||||
end
|
||||
|
||||
def starred?
|
||||
return has_tag?(Todo::STARRED_TAG_NAME)
|
||||
has_tag?(Todo::STARRED_TAG_NAME)
|
||||
end
|
||||
|
||||
def get_due_date(previous)
|
||||
case self.target
|
||||
when 'due_date'
|
||||
return get_next_date(previous)
|
||||
get_next_date(previous)
|
||||
when 'show_from_date'
|
||||
# so leave due date empty
|
||||
return nil
|
||||
nil
|
||||
else
|
||||
raise Exception.new, "unexpected value of recurrence target '#{self.target}'"
|
||||
end
|
||||
|
|
@ -561,7 +505,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
|
||||
# go back to day
|
||||
end
|
||||
return Time.zone.local(start.year, start.month, day)
|
||||
Time.zone.local(start.year, start.month, day)
|
||||
|
||||
when 1 # relative weekday of a month
|
||||
the_next = get_xth_day_of_month(self.every_other3, self.every_count, start.month, start.year)
|
||||
|
|
@ -580,11 +524,10 @@ class RecurringTodo < ActiveRecord::Base
|
|||
# support 5th day of the month, we need to handle this case
|
||||
the_next = get_xth_day_of_month(self.every_other3, self.every_count, the_next.month, the_next.year)
|
||||
end
|
||||
return the_next
|
||||
the_next
|
||||
else
|
||||
raise Exception.new, "unknown monthly recurrence selection (#{self.recurrence_selector})"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def get_xth_day_of_month(x, weekday, month, year)
|
||||
|
|
@ -596,7 +539,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
last_day -= 1.day
|
||||
end
|
||||
# convert back to local timezone
|
||||
return Time.zone.local(last_day.year, last_day.month, last_day.day)
|
||||
Time.zone.local(last_day.year, last_day.month, last_day.day)
|
||||
else
|
||||
# 1-4th -> count upwards last -> count backwards. use UTC to avoid strange
|
||||
# timezone oddities where last_day -= 1.day seems to shift tz+0100 to
|
||||
|
|
@ -611,7 +554,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
start += 1.day unless n==0
|
||||
end
|
||||
# convert back to local timezone
|
||||
return Time.zone.local(start.year, start.month, start.day)
|
||||
Time.zone.local(start.year, start.month, start.day)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -630,7 +573,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
# if there is a next month n, stay in this year
|
||||
start = Time.zone.local(start.year, month, 1)
|
||||
end
|
||||
return Time.zone.local(start.year, month, day)
|
||||
Time.zone.local(start.year, month, day)
|
||||
|
||||
when 1 # relative weekday of a specific month
|
||||
# if there is no next month n in this year, search in next year
|
||||
|
|
@ -643,11 +586,10 @@ class RecurringTodo < ActiveRecord::Base
|
|||
# year
|
||||
the_next = get_xth_day_of_month(self.every_other3, self.every_count, month, start.year+1) if the_next <= start
|
||||
|
||||
return the_next
|
||||
the_next
|
||||
else
|
||||
raise Exception.new, "unknown monthly recurrence selection (#{self.recurrence_selector})"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
def continues_recurring?(previous)
|
||||
|
|
@ -656,9 +598,9 @@ class RecurringTodo < ActiveRecord::Base
|
|||
|
||||
case self.target
|
||||
when 'due_date'
|
||||
return get_due_date(previous) <= self.end_date
|
||||
get_due_date(previous) <= self.end_date
|
||||
when 'show_from_date'
|
||||
return get_show_from_date(previous) <= self.end_date
|
||||
get_show_from_date(previous) <= self.end_date
|
||||
else
|
||||
raise Exception.new, "unexpected value of recurrence target '#{self.target}'"
|
||||
end
|
||||
|
|
@ -669,7 +611,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def toggle_completion!
|
||||
return completed? ? activate! : complete!
|
||||
completed? ? activate! : complete!
|
||||
end
|
||||
|
||||
def toggle_star!
|
||||
|
|
@ -706,20 +648,16 @@ class RecurringTodo < ActiveRecord::Base
|
|||
# Determine start date to calculate next date for recurring todo
|
||||
# offset needs to be 1.day for daily patterns
|
||||
def determine_start(previous, offset=0.day)
|
||||
|
||||
if previous.nil?
|
||||
start = self.start_from.nil? ? Time.zone.now : self.start_from
|
||||
# skip to present
|
||||
start = Time.zone.now if Time.zone.now > start
|
||||
else
|
||||
start = previous + offset
|
||||
|
||||
start = self.start_from || NullTime.new
|
||||
now = Time.zone.now
|
||||
if previous
|
||||
# check if the start_from date is later than previous. If so, use
|
||||
# start_from as start to search for next date
|
||||
start = self.start_from if ( self.start_from && self.start_from > previous )
|
||||
start > previous ? start : previous + offset
|
||||
else
|
||||
# skip to present
|
||||
start > now ? start : now
|
||||
end
|
||||
|
||||
return start
|
||||
end
|
||||
|
||||
def find_first_day_in_this_week(start)
|
||||
|
|
@ -727,7 +665,7 @@ class RecurringTodo < ActiveRecord::Base
|
|||
start.wday().upto 6 do |i|
|
||||
return start + (i-start.wday()).days unless self.every_day[i,1] == ' '
|
||||
end
|
||||
return -1
|
||||
-1
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -381,48 +381,6 @@ class Todo < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
# Rich Todo API
|
||||
def self.from_rich_message(user, default_context_id, description, notes)
|
||||
fields = description.match(/([^>@]*)@?([^>]*)>?(.*)/)
|
||||
description = fields[1].strip
|
||||
context = fields[2].strip
|
||||
project = fields[3].strip
|
||||
|
||||
context = nil if context == ""
|
||||
project = nil if project == ""
|
||||
|
||||
context_id = default_context_id
|
||||
unless(context.nil?)
|
||||
found_context = user.contexts.active.where("name like ?", "%#{context}%").first
|
||||
found_context = user.contexts.where("name like ?", "%#{context}%").first if !found_context
|
||||
context_id = found_context.id if found_context
|
||||
end
|
||||
|
||||
unless user.contexts.exists? context_id
|
||||
raise(CannotAccessContext, "Cannot access a context that does not belong to this user.")
|
||||
end
|
||||
|
||||
project_id = nil
|
||||
unless(project.blank?)
|
||||
if(project[0..3].downcase == "new:")
|
||||
found_project = user.projects.build
|
||||
found_project.name = project[4..255+4].strip
|
||||
found_project.save!
|
||||
else
|
||||
found_project = user.projects.active.find_by_namepart(project)
|
||||
found_project = user.projects.find_by_namepart(project) if found_project.nil?
|
||||
end
|
||||
project_id = found_project.id unless found_project.nil?
|
||||
end
|
||||
|
||||
todo = user.todos.build
|
||||
todo.description = description
|
||||
todo.raw_notes = notes
|
||||
todo.context_id = context_id
|
||||
todo.project_id = project_id unless project_id.nil?
|
||||
return todo
|
||||
end
|
||||
|
||||
def render_note
|
||||
unless self.notes.nil?
|
||||
self.rendered_notes = Tracks::Utils.render_text(self.notes)
|
||||
|
|
|
|||
28
app/services/rich_message_extractor.rb
Normal file
28
app/services/rich_message_extractor.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
class RichMessageExtractor
|
||||
|
||||
RICH_MESSAGE_FIELDS_REGEX = /([^>@]*)@?([^>]*)>?(.*)/
|
||||
|
||||
def initialize(message)
|
||||
@message = message
|
||||
end
|
||||
|
||||
def description
|
||||
fields[1].strip
|
||||
end
|
||||
|
||||
def context
|
||||
fields[2].strip
|
||||
end
|
||||
|
||||
def project
|
||||
stripped = fields[3].strip
|
||||
stripped.blank? ? nil : stripped
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fields
|
||||
@message.match(RICH_MESSAGE_FIELDS_REGEX)
|
||||
end
|
||||
|
||||
end
|
||||
49
app/services/todo_from_rich_message.rb
Normal file
49
app/services/todo_from_rich_message.rb
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
class TodoFromRichMessage
|
||||
|
||||
attr_reader :user, :default_context_id, :description, :notes
|
||||
|
||||
def initialize(user, default_context_id, description, notes)
|
||||
@user = user
|
||||
@default_context_id = default_context_id
|
||||
@description = description
|
||||
@notes = notes
|
||||
end
|
||||
|
||||
def construct
|
||||
extractor = RichMessageExtractor.new(description)
|
||||
description = extractor.description
|
||||
context = extractor.context
|
||||
project = extractor.project
|
||||
|
||||
context_id = default_context_id
|
||||
unless context.blank?
|
||||
found_context = user.contexts.active.where("name like ?", "%#{context}%").first
|
||||
found_context = user.contexts.where("name like ?", "%#{context}%").first if !found_context
|
||||
context_id = found_context.id if found_context
|
||||
end
|
||||
|
||||
unless user.context_ids.include? context_id
|
||||
raise(CannotAccessContext, "Cannot access a context that does not belong to this user.")
|
||||
end
|
||||
|
||||
project_id = nil
|
||||
unless project.blank?
|
||||
if project[0..3].downcase == "new:"
|
||||
found_project = user.projects.build
|
||||
found_project.name = project[4..259].strip
|
||||
found_project.save!
|
||||
else
|
||||
found_project = user.projects.active.find_by_namepart(project)
|
||||
found_project = user.projects.find_by_namepart(project) if found_project.nil?
|
||||
end
|
||||
project_id = found_project.id unless found_project.nil?
|
||||
end
|
||||
|
||||
todo = user.todos.build
|
||||
todo.description = description
|
||||
todo.raw_notes = notes
|
||||
todo.context_id = context_id
|
||||
todo.project_id = project_id unless project_id.nil?
|
||||
todo
|
||||
end
|
||||
end
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
<%-
|
||||
url_array = Array.new(13){ |i| url_for :controller => 'stats', :action => 'actions_done_last_years'}
|
||||
created_count_array = Array.new(13){ |i| @actions_created_last12months.size/12.0 }
|
||||
done_count_array = Array.new(13){ |i| @actions_done_last12months.size/12.0 }
|
||||
month_names = Array.new(13){ |i| t('date.month_names')[ (Time.now.mon - i -1 ) % 12 + 1 ]}
|
||||
<%-
|
||||
url = url_for :controller => 'stats', :action => 'actions_done_last_years'
|
||||
-%>
|
||||
&title=<%= t('stats.actions_lastyear_title') %>,{font-size:16},&
|
||||
&y_legend=<%= t('stats.legend.number_of_actions') %>,12,0x736AFF&
|
||||
|
|
@ -17,18 +14,18 @@ month_names = Array.new(13){ |i| t('date.month_names')[ (Time.now.mon -
|
|||
&line_7=1,0xAA0000&
|
||||
&line_8=1,0x007700&
|
||||
&values=<%= @actions_created_last12months_array.join(",")%>&
|
||||
&links=<%= url_array.join(",")%>&
|
||||
&links_2=<%= url_array.join(",")%>&
|
||||
&links=<%= Array.new(13,url).join(",") %>&
|
||||
&links_2=<%= Array.new(13,url).join(",") %>&
|
||||
&values_2=<%= @actions_done_last12months_array.join(",")%>&
|
||||
&values_3=<%= created_count_array.join(",")%>&
|
||||
&values_4=<%= done_count_array.join(",")%>&
|
||||
&values_3=<%= @created_count_array.join(",")%>&
|
||||
&values_4=<%= @done_count_array.join(",")%>&
|
||||
&values_5=<%= @actions_created_avg_last12months_array.join(",")%>&
|
||||
&values_6=<%= @actions_done_avg_last12months_array.join(",")%>&
|
||||
&values_7=<%= @interpolated_actions_created_this_month%>,<%=@actions_done_avg_last12months_array[1]%>&
|
||||
&values_8=<%= @interpolated_actions_done_this_month%>,<%=@actions_created_avg_last12months_array[1]%>&
|
||||
&x_labels=<%= month_names.join(",")%>&
|
||||
&x_labels=<%= @month_names.join(",")%>&
|
||||
&y_min=0&
|
||||
<% # add one to @max for people who have no actions completed yet.
|
||||
# OpenFlashChart cannot handle y_max=0 -%>
|
||||
&y_max=<%=@max+@max/10+1-%>&
|
||||
&x_label_style=9,,2,&
|
||||
&x_label_style=9,,2,&
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
<%-
|
||||
created_count_array = Array.new(@month_count+1){ |i| @actions_created_last_months.size/@month_count }
|
||||
done_count_array = Array.new(@month_count+1){ |i| @actions_done_last_months.size/@month_count }
|
||||
month_names = Array.new(@month_count+1){ |i| t('date.month_names')[ (Time.now.mon - i -1 ) % 12 + 1 ]+ " " + (Time.now - i.months).year.to_s}
|
||||
-%>
|
||||
&title=<%= t('stats.actions_last_year') %>,{font-size:16},&
|
||||
&y_legend=<%= t('stats.actions_last_year_legend.number_of_actions') %>,12,0x736AFF&
|
||||
&x_legend=<%= t('stats.actions_last_year_legend.months_ago') %>,12,0x736AFF&
|
||||
|
|
@ -17,15 +12,15 @@ month_names = Array.new(@month_count+1){ |i| t('date.month_names')[ (Tim
|
|||
&line_8=1,0x007700&
|
||||
&values=<%= @actions_created_last_months_array.join(",")%>&
|
||||
&values_2=<%= @actions_done_last_months_array.join(",")%>&
|
||||
&values_3=<%= created_count_array.join(",")%>&
|
||||
&values_4=<%= done_count_array.join(",")%>&
|
||||
&values_3=<%= @created_count_array.join(",")%>&
|
||||
&values_4=<%= @done_count_array.join(",")%>&
|
||||
&values_5=<%= @actions_created_avg_last_months_array.join(",")%>&
|
||||
&values_6=<%= @actions_done_avg_last_months_array.join(",")%>&
|
||||
&values_7=<%= @interpolated_actions_created_this_month%>,<%=@actions_done_avg_last_months_array[1]%>&
|
||||
&values_8=<%= @interpolated_actions_done_this_month%>,<%=@actions_created_avg_last_months_array[1]%>&
|
||||
&x_labels=<%= month_names.join(",")%>&
|
||||
&x_labels=<%= @month_names.join(",")%>&
|
||||
&y_min=0&
|
||||
<% # add one to @max for people who have no actions completed yet.
|
||||
# OpenFlashChart cannot handle y_max=0 -%>
|
||||
&y_max=<%=@max+@max/10+1-%>&
|
||||
&x_label_style=9,,2,&
|
||||
&x_label_style=9,,2,&
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ module Tracksapp
|
|||
config.assets.paths << Rails.root.join("app", "assets", "swfs")
|
||||
|
||||
# add print and login css to assets
|
||||
config.assets.precompile += %w(login.css print.css)
|
||||
config.assets.precompile += %w(login.css print.css mobile.css)
|
||||
|
||||
# configure Tracks to handle deployment in a subdir
|
||||
config.action_controller.relative_url_root = SITE_CONFIG['subdir'] if SITE_CONFIG['subdir']
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ en:
|
|||
due_this_week: Due in rest of this week
|
||||
due_next_week: Due next week
|
||||
due_this_month: Due in rest of %{month}
|
||||
due_after_this_month: Due in %{month} and later
|
||||
due_after_this_month: Due in %{next_month} and later
|
||||
show_tomorrow: Show Tomorrow
|
||||
tagged_page_title: "TRACKS::Tagged with '%{tag_name}'"
|
||||
action_deferred: "The action '%{description}' was deferred"
|
||||
|
|
@ -653,7 +653,7 @@ en:
|
|||
daily: Daily
|
||||
yearly_every_x_day: Every %{month} %{day}
|
||||
recurrence_on:
|
||||
options: Use the calculated date to
|
||||
options: Use the calculated date to
|
||||
due_date: set the actions due date
|
||||
show_options: Show the action
|
||||
show_always: always
|
||||
|
|
@ -1022,4 +1022,4 @@ en:
|
|||
notes_matching_query: Notes matching query
|
||||
no_results: Your search yielded no results.
|
||||
todos_matching_query: Todos matching query
|
||||
projects_matching_query: Projects matching query
|
||||
projects_matching_query: Projects matching query
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ nl:
|
|||
- Vr
|
||||
- Za
|
||||
abbr_month_names:
|
||||
-
|
||||
-
|
||||
- Jan
|
||||
- Feb
|
||||
- Maa
|
||||
|
|
@ -223,7 +223,7 @@ nl:
|
|||
only_day: '%e'
|
||||
short: '%e %b'
|
||||
month_names:
|
||||
-
|
||||
-
|
||||
- Januari
|
||||
- Februari
|
||||
- Maart
|
||||
|
|
@ -819,7 +819,7 @@ nl:
|
|||
due_this_week: Deadline in rest van deze week
|
||||
due_today: Deadline vandaag
|
||||
get_in_ical_format: Ontvang deze agenda in iCal-formaat
|
||||
due_after_this_month: Deadline in %{month} en later
|
||||
due_after_this_month: Deadline in %{next_month} en later
|
||||
calendar_page_title: TRACKS::Agenda
|
||||
cannot_add_dependency_to_completed_todo: Kan deze actie niet als een afhankelijkheid
|
||||
van een voltooide actie toevoegen!
|
||||
|
|
@ -957,7 +957,7 @@ nl:
|
|||
from: vanaf
|
||||
last: laatste
|
||||
month_names:
|
||||
-
|
||||
-
|
||||
- januari
|
||||
- februari
|
||||
- maart
|
||||
|
|
|
|||
|
|
@ -109,9 +109,9 @@ class StatsControllerTest < ActionController::TestCase
|
|||
assert_response :success
|
||||
|
||||
# Then the todos for the chart should be retrieved
|
||||
assert_not_nil assigns['actions_done_last12months']
|
||||
assert_not_nil assigns['actions_created_last12months']
|
||||
assert_equal 7, assigns['actions_created_last12months'].count, "very old todo should not be retrieved"
|
||||
#assert_not_nil assigns['actions_done_last12months']
|
||||
#assert_not_nil assigns['actions_created_last12months']
|
||||
#assert_equal 7, assigns['actions_created_last12months'].count, "very old todo should not be retrieved"
|
||||
|
||||
# And they should be totalled in a hash
|
||||
assert_equal 2, assigns['actions_created_last12months_array'][0], "there should be two todos in current month"
|
||||
|
|
@ -172,9 +172,6 @@ class StatsControllerTest < ActionController::TestCase
|
|||
|
||||
# only tests difference with actions_done_last_12months_data
|
||||
|
||||
# Then the count of months should be calculated
|
||||
assert_equal 27, assigns['month_count'], "two years and three months of last todo"
|
||||
|
||||
# And the last two months are corrected
|
||||
assert_equal 2/3.0, assigns['actions_done_avg_last_months_array'][23]
|
||||
assert_equal 2/3.0, assigns['actions_done_avg_last_months_array'][24]
|
||||
|
|
|
|||
55
test/models/rich_message_extractor_test.rb
Normal file
55
test/models/rich_message_extractor_test.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
require 'test/unit'
|
||||
require 'active_support/core_ext/object/blank'
|
||||
require_relative '../../app/services/rich_message_extractor.rb'
|
||||
|
||||
class RichMessageExtractorTest < Test::Unit::TestCase
|
||||
|
||||
def test_message_with_all_options
|
||||
message = "ohai@some-context>in-this-project"
|
||||
extractor = RichMessageExtractor.new(message)
|
||||
assert_equal "ohai", extractor.description
|
||||
assert_equal "some-context", extractor.context
|
||||
assert_equal "in-this-project", extractor.project
|
||||
end
|
||||
|
||||
def test_message_without_project
|
||||
message = "ohai @ some-context"
|
||||
extractor = RichMessageExtractor.new(message)
|
||||
assert_equal "ohai", extractor.description
|
||||
assert_equal "some-context", extractor.context
|
||||
assert_equal nil, extractor.project
|
||||
end
|
||||
|
||||
def test_message_without_project
|
||||
message = " ohai @ some-context"
|
||||
extractor = RichMessageExtractor.new(message)
|
||||
assert_equal "ohai", extractor.description
|
||||
assert_equal "some-context", extractor.context
|
||||
assert_equal nil, extractor.project
|
||||
end
|
||||
|
||||
def test_message_without_project_or_context
|
||||
message = "ohai"
|
||||
extractor = RichMessageExtractor.new(message)
|
||||
assert_equal "ohai", extractor.description
|
||||
assert_equal "", extractor.context
|
||||
assert_equal nil, extractor.project
|
||||
end
|
||||
|
||||
def test_message_without_anything
|
||||
message = ""
|
||||
extractor = RichMessageExtractor.new(message)
|
||||
assert_equal "", extractor.description
|
||||
assert_equal "", extractor.context
|
||||
assert_equal nil, extractor.project
|
||||
end
|
||||
|
||||
def test_message_with_just_a_context
|
||||
message = "@some-context"
|
||||
extractor = RichMessageExtractor.new(message)
|
||||
assert_equal "", extractor.description
|
||||
assert_equal "some-context", extractor.context
|
||||
assert_equal nil, extractor.project
|
||||
end
|
||||
|
||||
end
|
||||
21
test/models/todo_from_rich_message_test.rb
Normal file
21
test/models/todo_from_rich_message_test.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
||||
|
||||
class TodoFromRichMessageTest < ActiveSupport::TestCase
|
||||
|
||||
def setup
|
||||
@completed = Todo.find(8)
|
||||
end
|
||||
|
||||
def test_from_rich_message_adds_to_default_context
|
||||
user = @completed.user
|
||||
default_context_id = @completed.context_id
|
||||
builder = TodoFromRichMessage.new(user, default_context_id, "new todo", "notes")
|
||||
new_todo = builder.construct
|
||||
|
||||
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
|
||||
|
|
@ -477,15 +477,4 @@ class TodoTest < ActiveSupport::TestCase
|
|||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue