backlog 0.21.1 → 0.21.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +19 -0
- data/app/controllers/application.rb +23 -5
- data/app/controllers/application.rb~ +207 -0
- data/app/controllers/periods_controller.rb +7 -3
- data/app/models/task.rb +4 -6
- data/app/models/user.rb +1 -0
- data/app/models/work_lock_nagger.rb +7 -5
- data/bin/backlog +14 -6
- data/etc/backlog.conf +9 -1
- data/test/functional/periods_controller_test.rb +54 -23
- metadata +4 -3
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
== 0.21.2 2008-02-08
|
2
|
+
|
3
|
+
=== Features
|
4
|
+
|
5
|
+
* Added ability to override the public application URL in the backlog.conf config file.
|
6
|
+
|
7
|
+
=== Fixes
|
8
|
+
|
9
|
+
* Changed so that End Work -> Start Work operations don't generate overlapping work records by default.
|
10
|
+
* Added checking of return code to the 'setup_unix' task so the script fails unless it can successfully
|
11
|
+
change to the postgresql administration user.
|
12
|
+
* Added "debug" and "bsd" options to administration script.
|
13
|
+
The "debug" option turns on tracing in the rake scripts.
|
14
|
+
The "bsd" option changes the postgresql admin user from "postgres" to "pgsql".
|
15
|
+
* Fixed bug 16427: http://rubyforge.org/tracker/index.php?func=detail&aid=16427&group_id=3829&atid=14750
|
16
|
+
When postponing the first task to a new sprint, the sprint is created and the task is postponed directly.
|
17
|
+
A white screen is displayed during the dialog, but it was the best solution I could find.
|
18
|
+
* Fixed the default host/port for Work Lock Nag email from localhost:3000 to read from the local network settings and backlog.conf.
|
19
|
+
|
1
20
|
== 0.21.1 2008-02-04
|
2
21
|
|
3
22
|
=== Features
|
@@ -71,7 +71,7 @@ class ApplicationController < ActionController::Base
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def rjs_detour_to(options)
|
74
|
-
store_detour(params)
|
74
|
+
store_detour(params, request.post?)
|
75
75
|
rjs_redirect_to(options)
|
76
76
|
end
|
77
77
|
|
@@ -80,7 +80,8 @@ class ApplicationController < ActionController::Base
|
|
80
80
|
render :template => 'redirect', :layout => false
|
81
81
|
end
|
82
82
|
|
83
|
-
def store_detour(options)
|
83
|
+
def store_detour(options, post = false)
|
84
|
+
options[:request_method] = :post if post
|
84
85
|
if session[:detours] && session[:detours].last == options
|
85
86
|
logger.debug "duplicate detour: #{options}"
|
86
87
|
return
|
@@ -102,7 +103,12 @@ class ApplicationController < ActionController::Base
|
|
102
103
|
def back_or_redirect_to(options)
|
103
104
|
if session[:detours]
|
104
105
|
detour = pop_detour
|
105
|
-
|
106
|
+
post = detour.delete(:request_method) == :post
|
107
|
+
if post
|
108
|
+
redirect_to_post(detour)
|
109
|
+
else
|
110
|
+
redirect_to detour
|
111
|
+
end
|
106
112
|
else
|
107
113
|
redirect_to options
|
108
114
|
end
|
@@ -143,7 +149,7 @@ class ApplicationController < ActionController::Base
|
|
143
149
|
# TODO (uwe): This does not scale!
|
144
150
|
#periods = Period.find(:all).select {|period| period.active_or_future?(true) && period.party.includes?(user)}
|
145
151
|
periods = Period.find_active_or_future(true)
|
146
|
-
|
152
|
+
|
147
153
|
|
148
154
|
@sidebars = periods.sort_by {|p| p.required_speed}.reverse.map do |period|
|
149
155
|
content = '<ul>'
|
@@ -186,4 +192,16 @@ class ApplicationController < ActionController::Base
|
|
186
192
|
User.find_by_id(user_id) if user_id
|
187
193
|
end
|
188
194
|
|
189
|
-
|
195
|
+
def redirect_to_post(options)
|
196
|
+
url = url_for options
|
197
|
+
render :text => <<EOF, :layout => false
|
198
|
+
<html>
|
199
|
+
<body onload="document.getElementById('form').submit()">
|
200
|
+
<form id="form" action="#{url}" method="POST">
|
201
|
+
</form>
|
202
|
+
</body>
|
203
|
+
</html>
|
204
|
+
EOF
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
class ApplicationController < ActionController::Base
|
2
|
+
include Localization
|
3
|
+
include UserSystem
|
4
|
+
include ApplicationHelper
|
5
|
+
include ActionView::Helpers::TagHelper
|
6
|
+
include ActionView::Helpers::JavaScriptHelper
|
7
|
+
include ActionView::Helpers::PrototypeHelper
|
8
|
+
include ActionView::Helpers::ScriptaculousHelper
|
9
|
+
include UrlForFix
|
10
|
+
|
11
|
+
layout :determine_layout
|
12
|
+
helper :user
|
13
|
+
before_filter :store_detour_from_params
|
14
|
+
before_filter :authenticate_user
|
15
|
+
before_filter :populate_layout
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@application_title = l :backlog
|
19
|
+
@application_description = l :backlog_description
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.in_place_edit_for(object, attribute, options = {})
|
23
|
+
define_method("set_#{object}_#{attribute}") do
|
24
|
+
@item = object.to_s.camelize.constantize.find(params[:id])
|
25
|
+
@item.update_attribute(attribute, params[:value])
|
26
|
+
render :text => @item.send(attribute).to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def determine_layout
|
33
|
+
if request.accepts.find {|mt| mt == 'xml'}
|
34
|
+
'wap'
|
35
|
+
else
|
36
|
+
# Firefox
|
37
|
+
#<Mime::Type:0xb79cd374 @synonyms=["application/xhtml+xml"], @string="text/html", @symbol=:html>
|
38
|
+
#<Mime::Type:0xb79cd1e4 @synonyms=["text/xml", "application/x-xml"], @string="application/xml", @symbol=:xml>
|
39
|
+
#<Mime::Type:0xb746d16c @synonyms=[], @string="image/png", @symbol=nil>
|
40
|
+
#<Mime::Type:0xb79cd3ec @synonyms=[], @string="text/plain", @symbol=:text>
|
41
|
+
#<Mime::Type:0xb79cd43c @synonyms=[], @string="*/*", @symbol=:all>
|
42
|
+
|
43
|
+
# nokia N80
|
44
|
+
#<Mime::Type:0xb79ab374 @synonyms=["application/xhtml+xml"], @string="text/html", @symbol=:html>
|
45
|
+
#<Mime::Type:0xb7308408 @synonyms=[], @string="text/css", @symbol=nil>
|
46
|
+
#<Mime::Type:0xb73082f0 @synonyms=[], @string="text/x-vcard", @symbol=nil>
|
47
|
+
#<Mime::Type:0xb73081ec @synonyms=[], @string="text/x-vcalendar", @symbol=nil>
|
48
|
+
#<Mime::Type:0xb73080d4 @synonyms=[], @string="image/gif", @symbol=nil>
|
49
|
+
#<Mime::Type:0xb7307fd0 @synonyms=[], @string="image/vnd.wap.wbmp", @symbol=nil>
|
50
|
+
#<Mime::Type:0xb79ab43c @synonyms=[], @string="*/*", @symbol=:all>
|
51
|
+
|
52
|
+
# SonyEricson K810i
|
53
|
+
#<Mime::Type:0xb72509d4 @synonyms=[], @string="multipart/mixed", @symbol=nil>
|
54
|
+
#<Mime::Type:0xb7250934 @synonyms=[], @string="application/vnd.wap.multipart.mixed", @symbol=nil>
|
55
|
+
#<Mime::Type:0xb7250880 @synonyms=[], @string="application/vnd.wap.xhtml+xml", @symbol=nil>
|
56
|
+
#<Mime::Type:0xb79ab374 @synonyms=["application/xhtml+xml"], @string="text/html", @symbol=:html>
|
57
|
+
#<Mime::Type:0xb72507cc @synonyms=[], @string="text/vnd.wap.wml", @symbol=nil>
|
58
|
+
#<Mime::Type:0xb73082f0 @synonyms=[], @string="text/x-vcard", @symbol=nil>
|
59
|
+
#<Mime::Type:0xb73081ec @synonyms=[], @string="text/x-vcalendar", @symbol=nil>
|
60
|
+
#<Mime::Type:0xb73080d4 @synonyms=[], @string="image/gif", @symbol=nil>
|
61
|
+
#<Mime::Type:0xb7307fd0 @synonyms=[], @string="image/vnd.wap.wbmp", @symbol=nil>
|
62
|
+
#<Mime::Type:0xb79ab43c @synonyms=[], @string="*/*", @symbol=:all>
|
63
|
+
|
64
|
+
'mwrt002'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def detour_to(options)
|
69
|
+
store_detour(params)
|
70
|
+
redirect_to(options)
|
71
|
+
end
|
72
|
+
|
73
|
+
def rjs_detour_to(options)
|
74
|
+
store_detour(params, request.post?)
|
75
|
+
rjs_redirect_to(options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def rjs_redirect_to(options)
|
79
|
+
@options = options
|
80
|
+
render :template => 'redirect', :layout => false
|
81
|
+
end
|
82
|
+
|
83
|
+
def store_detour(options, post = false)
|
84
|
+
options[:request_method] = :post if post
|
85
|
+
if session[:detours] && session[:detours].last == options
|
86
|
+
logger.debug "duplicate detour: #{options}"
|
87
|
+
return
|
88
|
+
end
|
89
|
+
logger.debug "adding detour: #{options}"
|
90
|
+
session[:detours] ||= []
|
91
|
+
session[:detours] << options
|
92
|
+
end
|
93
|
+
|
94
|
+
def store_detour_from_params
|
95
|
+
if params[:detour]
|
96
|
+
store_detour(params[:detour])
|
97
|
+
end
|
98
|
+
if params[:return_from_detour] && session[:detours]
|
99
|
+
pop_detour
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def back_or_redirect_to(options)
|
104
|
+
if session[:detours]
|
105
|
+
detour = pop_detour
|
106
|
+
post = detour.delete(:request_method) == :post
|
107
|
+
if post
|
108
|
+
redirect_to_post(detour)
|
109
|
+
else
|
110
|
+
redirect_to detour
|
111
|
+
end
|
112
|
+
else
|
113
|
+
redirect_to options
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def pop_detour
|
118
|
+
detours = session[:detours]
|
119
|
+
return nil unless detours
|
120
|
+
detour = detours.pop
|
121
|
+
logger.debug "popped detour: #{detour.inspect} #{session[:detours].size} more"
|
122
|
+
if detours.empty?
|
123
|
+
session[:detours] = nil
|
124
|
+
end
|
125
|
+
detour
|
126
|
+
end
|
127
|
+
private :pop_detour
|
128
|
+
|
129
|
+
def populate_shortcuts
|
130
|
+
@shortcuts = [
|
131
|
+
{:key => 'Alt-N', :function => :new_task, :options => {:controller => 'tasks', :action => 'new', :period_id => (@period ? @period.id : (@backlog && @backlog.periods.first ? @backlog.periods.first.id : nil))}},
|
132
|
+
{:key => 'Alt-Shift-N', :function => :new_period, :options => {:controller => 'periods', :action => 'new'}},
|
133
|
+
{:key => 'Alt-Ctrl-N', :function => :new_backlog, :options => {:controller => 'backlogs', :action => 'new'}},
|
134
|
+
{:key => 'Alt-Ctrl-G', :function => :new_group, :options => {:controller => 'groups', :action => :new}},
|
135
|
+
{:key => "Alt-#{l :up}", :function => :up},
|
136
|
+
{:key => "Alt-#{l :down}", :function => :down},
|
137
|
+
{:key => "Alt-Shift-#{l :left}", :function => :move_to_top},
|
138
|
+
{:key => "Alt-Shift-#{l :right}", :function => :move_to_bottom},
|
139
|
+
{:key => 'Alt-X', :function => :complete},
|
140
|
+
{:key => 'Alt-Q', :function => :reopen},
|
141
|
+
]
|
142
|
+
end
|
143
|
+
|
144
|
+
def populate_layout
|
145
|
+
return true if request.path_parameters[:action] =~ /_no_layout$/
|
146
|
+
|
147
|
+
populate_shortcuts
|
148
|
+
|
149
|
+
# TODO (uwe): This does not scale!
|
150
|
+
#periods = Period.find(:all).select {|period| period.active_or_future?(true) && period.party.includes?(user)}
|
151
|
+
periods = Period.find_active_or_future(true)
|
152
|
+
|
153
|
+
|
154
|
+
@sidebars = periods.sort_by {|p| p.required_speed}.reverse.map do |period|
|
155
|
+
content = '<ul>'
|
156
|
+
period.tasks.select {|task| task.in_list? }[0...5].map do |task|
|
157
|
+
"<li>#{task.description}</li>"
|
158
|
+
end.each do |period_link|
|
159
|
+
content << "#{period_link}"
|
160
|
+
end
|
161
|
+
content << "</ul>\n"
|
162
|
+
content << drop_receiving_element("sidebar_#{period.id}",
|
163
|
+
:url => with_detour({:action => "move_task_to_period", :period_id => period.id, :layout => false}),
|
164
|
+
:accept => "tasks", :loading => "", :complete => "",
|
165
|
+
:hoverclass => 'highlight')
|
166
|
+
|
167
|
+
{ :id => period.id,
|
168
|
+
:title => "#{period.party.name}##{period.position} (#{'%0.1f' % period.required_speed})",
|
169
|
+
:options => {:controller => 'periods', :action => :show, :id => period},
|
170
|
+
:content => content
|
171
|
+
}
|
172
|
+
end
|
173
|
+
started_tasks = Task.find_started
|
174
|
+
if not started_tasks.empty?
|
175
|
+
links = started_tasks.map do |task|
|
176
|
+
"<li><a href=\"#{url_for :controller => 'tasks', :action => :list_started, :id => task.id}\">#{task.description}</a></li>"
|
177
|
+
end
|
178
|
+
@sidebars.unshift({ :title => l(:started_tasks),
|
179
|
+
:options => {:controller => 'tasks', :action => :list_started},
|
180
|
+
:content => "<ul>#{links}"
|
181
|
+
})
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
private
|
186
|
+
|
187
|
+
def user_id
|
188
|
+
session[:user_id]
|
189
|
+
end
|
190
|
+
|
191
|
+
def user
|
192
|
+
User.find_by_id(user_id) if user_id
|
193
|
+
end
|
194
|
+
|
195
|
+
def redirect_to_post(options)
|
196
|
+
url = url_for options
|
197
|
+
render :text => <<EOF, :layout => false
|
198
|
+
<html>
|
199
|
+
<body onload="alert('submitting');document.getElementById('form').submit()">
|
200
|
+
<form id="form" action="#{url}" method="POST">
|
201
|
+
</form>
|
202
|
+
</body>
|
203
|
+
</html>
|
204
|
+
EOF
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -130,12 +130,16 @@ class PeriodsController < ApplicationController
|
|
130
130
|
next_task = @task.higher_item ? @task.higher_item : @task.lower_item ? @task.lower_item : @task
|
131
131
|
@task.move_to_period period
|
132
132
|
load_tasks(@task.period)
|
133
|
-
|
133
|
+
if request.xhr?
|
134
|
+
render :action => :move_task_to_period, :layout => false
|
135
|
+
else
|
136
|
+
redirect_to :action => :show, :id => @task.period, :task_id => @task.id, :layout => false
|
137
|
+
end
|
134
138
|
else
|
135
|
-
rjs_detour_to :
|
139
|
+
rjs_detour_to :action => :new, :period => {:party_id => @task.period.party_id}, :layout => false
|
136
140
|
end
|
137
141
|
else
|
138
|
-
redirect_to :
|
142
|
+
redirect_to :action => :show, :id => @task.period, :task_id => @task.id, :layout => false
|
139
143
|
end
|
140
144
|
end
|
141
145
|
|
data/app/models/task.rb
CHANGED
@@ -348,17 +348,15 @@ class Task < ActiveRecord::Base
|
|
348
348
|
new_work.task = self
|
349
349
|
|
350
350
|
new_work.started_at = Time.previous_quarter
|
351
|
-
if works.size > 0
|
352
351
|
if current_user
|
353
|
-
last_work = works.
|
354
|
-
|
355
|
-
|
356
|
-
last_work = works.select {|work| work.user.nil?}.last
|
352
|
+
last_work = current_user.works.last
|
353
|
+
else
|
354
|
+
last_work = Work.find(:first, :order => 'compeleted_at DESC')
|
357
355
|
end
|
358
356
|
if last_work && last_work.completed_at > new_work.started_at
|
359
357
|
new_work.started_at = last_work.completed_at
|
360
358
|
end
|
361
|
-
|
359
|
+
|
362
360
|
new_work.user = current_user
|
363
361
|
new_work.work_account_id = work_account.id
|
364
362
|
new_work.save!
|
data/app/models/user.rb
CHANGED
@@ -9,6 +9,7 @@ class User < Party
|
|
9
9
|
# even if they follow the defaults since ClassTableInheritanceInRails breaks it.
|
10
10
|
has_and_belongs_to_many :groups, :join_table => "groups_users", :foreign_key => "user_id", :association_foreign_key => 'group_id'
|
11
11
|
has_and_belongs_to_many :work_lock_subscribers, :class_name => 'User', :join_table => "user_work_lock_subscriptions", :foreign_key => "user_id", :association_foreign_key => 'subscriber_user_id'
|
12
|
+
has_many :works, :foreign_key => :user_id, :order => :completed_at
|
12
13
|
has_many :work_locks, :foreign_key => :user_id, :order => :end_on
|
13
14
|
|
14
15
|
attr_accessor :password_needs_confirmation
|
@@ -1,16 +1,18 @@
|
|
1
1
|
class WorkLockNagger
|
2
2
|
include ActionController::UrlWriter
|
3
3
|
|
4
|
-
puts "Loading class"
|
5
|
-
|
6
4
|
def initialize
|
7
|
-
puts "Worker initialized"
|
8
5
|
end
|
9
6
|
|
10
7
|
def nag
|
11
|
-
|
8
|
+
sleep 1.minute
|
9
|
+
puts "Work Lock Nagger started"
|
12
10
|
begin
|
13
|
-
|
11
|
+
host = Socket::gethostbyname('localhost')[1][1]
|
12
|
+
config = YAML::load(ERB.new(IO.read(APP_CONFIG_FILE)).result) || {}
|
13
|
+
port = config[:port] || 3000
|
14
|
+
|
15
|
+
url = url_for(:host => host, :port => port, :controller => 'works', :action => :weekly_work_sheet_by_work_account)
|
14
16
|
rescue Exception => e
|
15
17
|
puts e.message
|
16
18
|
puts e.backtrace
|
data/bin/backlog
CHANGED
@@ -114,23 +114,31 @@ when 'status'
|
|
114
114
|
exit 3
|
115
115
|
end
|
116
116
|
when 'setup_unix'
|
117
|
+
puts "Starting setup on #{RUBY_PLATFORM}"
|
118
|
+
bsd = ARGV[1..-1].include? 'bsd'
|
119
|
+
debug = ARGV[1..-1].include? 'debug'
|
120
|
+
pg_admin_user = bsd ? 'pgsql' : 'postgres'
|
117
121
|
current_user = `whoami`
|
118
|
-
users = `su -
|
122
|
+
users = `su - #{pg_admin_user} -c "echo '\\du' | psql template1"`
|
123
|
+
raise "Could not list users: #{$? >> 8}:#{$? & 0xff}" unless ($? >> 8) == 0
|
119
124
|
unless users =~ /root/
|
120
125
|
puts users
|
121
126
|
createuser_command = `which createuser`.chomp
|
122
|
-
puts `su -
|
127
|
+
puts `su - #{pg_admin_user} -c "#{createuser_command} -dAR #{current_user}"`
|
123
128
|
end
|
124
|
-
dbs = `su -
|
129
|
+
dbs = `su - #{pg_admin_user} -c "echo '\\l' | psql template1"`
|
125
130
|
unless dbs =~ /#{APPLICATION}_production/
|
126
131
|
puts dbs
|
127
132
|
createdb_command = `which createdb`.chomp
|
128
|
-
puts `su -
|
133
|
+
puts `su - #{pg_admin_user} -c "#{createdb_command} #{APPLICATION}_production"`
|
134
|
+
raise "Could not create database: #{$? >> 8}:#{$? & 0xff}" unless ($? >> 8) == 0
|
129
135
|
end
|
136
|
+
FileUtils.mkdir_p INSTALL_DIR
|
130
137
|
Dir.chdir INSTALL_DIR
|
131
138
|
Dir.mkdir LOG_DIR unless File.exists? LOG_DIR
|
132
139
|
ENV['RAILS_ENV'] = 'production'
|
133
|
-
puts `rake db:migrate`
|
140
|
+
puts `rake db:migrate #{'--trace' if debug}`
|
141
|
+
raise "Could not migrate database: #{$? >> 8}:#{$? & 0xff}" unless ($? >> 8) == 0
|
134
142
|
|
135
143
|
# TODO: provide startup information based on launchd in OS X versions >= 10.4
|
136
144
|
if File.directory? '/etc/init.d'
|
@@ -144,7 +152,7 @@ when 'setup_unix'
|
|
144
152
|
`su - -c "chkconfig #{APPLICATION} on"`
|
145
153
|
puts
|
146
154
|
else
|
147
|
-
puts "Usage: #$0 {start|stop|restart|status|setup_unix}"
|
155
|
+
puts "Usage: #$0 {start|stop|restart|status|setup_unix [bsd] [debug]}"
|
148
156
|
exit 1
|
149
157
|
end
|
150
158
|
|
data/etc/backlog.conf
CHANGED
@@ -1,9 +1,17 @@
|
|
1
|
+
# Uncomment the following line to set the public url for this server.
|
2
|
+
# Default url is http://localhost:3000/
|
3
|
+
|
4
|
+
# Examples:
|
5
|
+
# app_url: http://localhost:3000/
|
6
|
+
# app_url: http://myhost.mydomain/
|
7
|
+
# app_url: http://myhost.mydomain/backlog
|
8
|
+
|
1
9
|
# Uncomment the following line to override the network port to listen on.
|
2
10
|
# Default port is 3000.
|
3
11
|
|
4
12
|
# port: 3000
|
5
13
|
|
6
|
-
# Uncomment
|
14
|
+
# Uncomment _one_ of the following sections to override the database connection settings.
|
7
15
|
|
8
16
|
# database:
|
9
17
|
# adapter: postgresql
|
@@ -126,15 +126,19 @@ class PeriodsControllerTest < Test::Unit::TestCase
|
|
126
126
|
|
127
127
|
post :move_task_to_next_period, :id => tasks(:another).id
|
128
128
|
|
129
|
-
assert_response :
|
129
|
+
assert_response :redirect
|
130
130
|
|
131
|
-
|
132
|
-
|
131
|
+
check_move_effects(before, :future)
|
132
|
+
end
|
133
|
+
|
134
|
+
def test_move_task_to_next_period_xhr
|
135
|
+
before = Task.find(tasks(:another).id)
|
133
136
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
137
|
+
xhr :post, :move_task_to_next_period, :id => tasks(:another).id
|
138
|
+
|
139
|
+
assert_response :success
|
140
|
+
|
141
|
+
check_move_effects(before, :future)
|
138
142
|
end
|
139
143
|
|
140
144
|
def test_move_task_to_next_period_from_past
|
@@ -143,15 +147,20 @@ class PeriodsControllerTest < Test::Unit::TestCase
|
|
143
147
|
|
144
148
|
post :move_task_to_next_period, :id => task.id
|
145
149
|
|
146
|
-
assert_response :
|
150
|
+
assert_response :redirect
|
147
151
|
|
148
|
-
|
149
|
-
|
152
|
+
check_move_effects(before, :active)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_move_task_to_next_period_from_past_xhr
|
156
|
+
task = tasks(:first)
|
157
|
+
before = Task.find(task.id)
|
150
158
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
159
|
+
xhr :post, :move_task_to_next_period, :id => task.id
|
160
|
+
|
161
|
+
assert_response :success
|
162
|
+
|
163
|
+
check_move_effects(before, :active)
|
155
164
|
end
|
156
165
|
|
157
166
|
def test_move_to_next_period_at_end
|
@@ -175,17 +184,20 @@ class PeriodsControllerTest < Test::Unit::TestCase
|
|
175
184
|
|
176
185
|
post :move_task_to_next_period, :id => before.id
|
177
186
|
|
178
|
-
assert_response :
|
187
|
+
assert_response :redirect
|
179
188
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
189
|
+
check_move_effects(before, :active)
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_move_to_next_period_from_ancient_xhr
|
193
|
+
before = tasks(:in_ancient)
|
194
|
+
previous_last_id = Task.find(:first, :order => 'id DESC').id
|
195
|
+
|
196
|
+
xhr :post, :move_task_to_next_period, :id => before.id
|
197
|
+
|
198
|
+
assert_response :success
|
184
199
|
|
185
|
-
|
186
|
-
assert_not_nil new
|
187
|
-
assert_equal before.id, new.previous_task_id
|
188
|
-
assert_equal 1, new.position
|
200
|
+
check_move_effects(before, :active)
|
189
201
|
end
|
190
202
|
|
191
203
|
def test_move_task_to_period_back_to_earlier_period
|
@@ -253,4 +265,23 @@ class PeriodsControllerTest < Test::Unit::TestCase
|
|
253
265
|
assert_nil after.resolution
|
254
266
|
end
|
255
267
|
|
268
|
+
private
|
269
|
+
|
270
|
+
def check_move_effects(before, period_sym)
|
271
|
+
after = Task.find(before.id)
|
272
|
+
assert_equal before.period_id, after.period_id
|
273
|
+
assert_equal Task::POSTPONED, after.resolution
|
274
|
+
assert_not_nil after.finished_at
|
275
|
+
|
276
|
+
newest_task = Task.find(:first, :order => 'id DESC')
|
277
|
+
new_task = Task.find_by_period_id_and_previous_task_id(periods(period_sym).id, before.id)
|
278
|
+
assert_not_nil newest_task
|
279
|
+
assert_not_nil new_task
|
280
|
+
assert_equal newest_task.id, new_task.id
|
281
|
+
assert_equal before.previous_task_id || before.id, new_task.previous_task_id
|
282
|
+
assert_nil new_task.finished_at
|
283
|
+
assert_nil new_task.resolution
|
284
|
+
assert_equal 1, new_task.position
|
285
|
+
end
|
286
|
+
|
256
287
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.21.
|
4
|
+
version: 0.21.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uwe Kubosch
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-08 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
requirements:
|
65
65
|
- - ">="
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: 1.
|
67
|
+
version: 1.5.0
|
68
68
|
version:
|
69
69
|
description: Backlog is a tool to help you collect and organize all your tasks, whether you are a single person or a small or large group. A time keeping module is also included to track time spent on the different tasks.
|
70
70
|
email: uwe@kubosch.no
|
@@ -209,6 +209,7 @@ files:
|
|
209
209
|
- app/controllers/welcome_controller.rb
|
210
210
|
- app/controllers/backlogs_controller.rb
|
211
211
|
- app/controllers/estimates_controller.rb
|
212
|
+
- app/controllers/application.rb~
|
212
213
|
- app/controllers/application.rb
|
213
214
|
- app/controllers/parties_controller.rb
|
214
215
|
- app/controllers/periods_controller.rb
|