timesheet_plugin 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/README.rdoc +1 -0
  2. data/Rakefile +2 -2
  3. data/VERSION +1 -1
  4. data/app/controllers/timesheet_controller.rb +16 -3
  5. data/app/helpers/timesheet_helper.rb +13 -8
  6. data/app/models/timesheet.rb +120 -12
  7. data/app/views/timesheet/_form.rhtml +5 -31
  8. data/app/views/timesheet/_issue_time_entries.rhtml +9 -2
  9. data/app/views/timesheet/index.rhtml +2 -5
  10. data/app/views/timesheet/report.rhtml +2 -5
  11. data/assets/images/csv.png +0 -0
  12. data/assets/javascripts/timesheet.js +17 -0
  13. data/assets/stylesheets/timesheet.css +6 -0
  14. data/config/locales/hu.yml +1 -1
  15. data/config/locales/hy.yml +9 -0
  16. data/config/locales/ja.yml +10 -0
  17. data/config/locales/pt-br.yml +10 -0
  18. data/config/locales/ru.yml +1 -0
  19. data/config/locales/sr.yml +10 -0
  20. data/config/locales/sv.yml +10 -0
  21. data/config/locales/uk.yml +10 -0
  22. data/config/routes.rb +4 -0
  23. data/init.rb +47 -1
  24. data/lang/hu.yml +1 -1
  25. data/lang/hy.yml +8 -0
  26. data/lang/ja.yml +9 -0
  27. data/lang/pt-br.yml +9 -0
  28. data/lang/ru.yml +1 -0
  29. data/lang/sr.yml +9 -0
  30. data/lang/sv.yml +9 -0
  31. data/lang/uk.yml +9 -0
  32. data/lib/timesheet_compatibility.rb +12 -1
  33. data/rails/init.rb +1 -29
  34. data/test/functional/timesheet_controller_test.rb +256 -0
  35. data/test/integration/timesheet_menu_test.rb +53 -0
  36. data/test/test_helper.rb +24 -0
  37. data/test/unit/sanity_test.rb +20 -0
  38. data/test/unit/timesheet_test.rb +653 -0
  39. metadata +28 -7
  40. data/lib/tasks/plugin_stat.rake +0 -38
  41. data/spec/controllers/timesheet_controller_spec.rb +0 -263
  42. data/spec/models/timesheet_spec.rb +0 -537
  43. data/spec/sanity_spec.rb +0 -7
  44. data/spec/spec_helper.rb +0 -40
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timesheet_plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Davis
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-03 00:00:00 -07:00
12
+ date: 2010-03-18 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -42,8 +42,11 @@ files:
42
42
  - app/views/timesheet/no_projects.rhtml
43
43
  - app/views/timesheet/report.rhtml
44
44
  - app/views/timesheet/timelog.rhtml
45
+ - assets/images/csv.png
45
46
  - assets/images/toggle-arrow-closed.gif
46
47
  - assets/images/toggle-arrow-open.gif
48
+ - assets/javascripts/timesheet.js
49
+ - assets/stylesheets/timesheet.css
47
50
  - config/locales/ca.yml
48
51
  - config/locales/cs.yml
49
52
  - config/locales/da.yml
@@ -52,10 +55,17 @@ files:
52
55
  - config/locales/es.yml
53
56
  - config/locales/fr.yml
54
57
  - config/locales/hu.yml
58
+ - config/locales/hy.yml
55
59
  - config/locales/it.yml
60
+ - config/locales/ja.yml
56
61
  - config/locales/lt.yml
57
62
  - config/locales/pl.yml
63
+ - config/locales/pt-br.yml
58
64
  - config/locales/ru.yml
65
+ - config/locales/sr.yml
66
+ - config/locales/sv.yml
67
+ - config/locales/uk.yml
68
+ - config/routes.rb
59
69
  - init.rb
60
70
  - lang/ca.yml
61
71
  - lang/cs.yml
@@ -65,13 +75,23 @@ files:
65
75
  - lang/es.yml
66
76
  - lang/fr.yml
67
77
  - lang/hu.yml
78
+ - lang/hy.yml
68
79
  - lang/it.yml
80
+ - lang/ja.yml
69
81
  - lang/lt.yml
70
82
  - lang/pl.yml
83
+ - lang/pt-br.yml
71
84
  - lang/ru.yml
72
- - lib/tasks/plugin_stat.rake
85
+ - lang/sr.yml
86
+ - lang/sv.yml
87
+ - lang/uk.yml
73
88
  - lib/timesheet_compatibility.rb
74
89
  - rails/init.rb
90
+ - test/functional/timesheet_controller_test.rb
91
+ - test/integration/timesheet_menu_test.rb
92
+ - test/test_helper.rb
93
+ - test/unit/sanity_test.rb
94
+ - test/unit/timesheet_test.rb
75
95
  has_rdoc: true
76
96
  homepage: https://projects.littlestreamsoftware.com/projects/redmine-timesheet
77
97
  licenses: []
@@ -101,7 +121,8 @@ signing_key:
101
121
  specification_version: 3
102
122
  summary: A Timesheet plugin for Redmine to show timelogs for all projects
103
123
  test_files:
104
- - spec/models/timesheet_spec.rb
105
- - spec/spec_helper.rb
106
- - spec/controllers/timesheet_controller_spec.rb
107
- - spec/sanity_spec.rb
124
+ - test/test_helper.rb
125
+ - test/integration/timesheet_menu_test.rb
126
+ - test/unit/timesheet_test.rb
127
+ - test/unit/sanity_test.rb
128
+ - test/functional/timesheet_controller_test.rb
@@ -1,38 +0,0 @@
1
- namespace :spec do
2
- task :statsetup do
3
- require 'code_statistics'
4
- ::STATS_DIRECTORIES << %w(Model\ specs spec/models) if File.exist?('spec/models')
5
- ::STATS_DIRECTORIES << %w(View\ specs spec/views) if File.exist?('spec/views')
6
- ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) if File.exist?('spec/controllers')
7
- ::STATS_DIRECTORIES << %w(Helper\ specs spec/helpers) if File.exist?('spec/helpers')
8
- ::STATS_DIRECTORIES << %w(Library\ specs spec/lib) if File.exist?('spec/lib')
9
- ::STATS_DIRECTORIES << %w(Routing\ specs spec/routing) if File.exist?('spec/routing')
10
- ::STATS_DIRECTORIES << %w(Integration\ specs spec/integration) if File.exist?('spec/integration')
11
- ::CodeStatistics::TEST_TYPES << "Model specs" if File.exist?('spec/models')
12
- ::CodeStatistics::TEST_TYPES << "View specs" if File.exist?('spec/views')
13
- ::CodeStatistics::TEST_TYPES << "Controller specs" if File.exist?('spec/controllers')
14
- ::CodeStatistics::TEST_TYPES << "Helper specs" if File.exist?('spec/helpers')
15
- ::CodeStatistics::TEST_TYPES << "Library specs" if File.exist?('spec/lib')
16
- ::CodeStatistics::TEST_TYPES << "Routing specs" if File.exist?('spec/routing')
17
- ::CodeStatistics::TEST_TYPES << "Integration specs" if File.exist?('spec/integration')
18
- end
19
- end
20
-
21
-
22
- STATS_DIRECTORIES = [
23
- %w(Controllers app/controllers),
24
- %w(Helpers app/helpers),
25
- %w(Models app/models),
26
- %w(Libraries lib/),
27
- %w(APIs app/apis),
28
- %w(Integration\ tests test/integration),
29
- %w(Functional\ tests test/functional),
30
- %w(Unit\ tests test/unit)
31
-
32
- ].collect { |name, dir| [ name, "./#{dir}" ] }.select { |name, dir| File.directory?(dir) }
33
-
34
- desc "Report code statistics (KLOCs, etc) from the application"
35
- task :stats do
36
- require 'code_statistics'
37
- CodeStatistics.new(*STATS_DIRECTORIES).to_s
38
- end
@@ -1,263 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- module TimesheetControllerHelper
4
- # Sets up the default mocks
5
- def default_mocks(options = {})
6
- # User
7
- @current_user = mock_model(User)
8
- @current_user.stub!(:admin?).and_return(false)
9
- @user_project_mock = mock_model(Project)
10
- @user_project_mock.stub!(:find).and_return([ ])
11
- @current_user.stub!(:projects).and_return(@user_project_mock)
12
- stub_current_user
13
-
14
- # Redmine application controller
15
- controller.stub!(:check_if_login_required).and_return(true)
16
- controller.stub!(:set_localization)
17
-
18
- # Timesheet
19
- @timesheet = mock_model(Timesheet)
20
- @timesheet.stub!(:projects).and_return([ ])
21
- @timesheet.stub!(:projects=)
22
- @timesheet.stub!(:allowed_projects).and_return(['not empty'])
23
- @timesheet.stub!(:allowed_projects=)
24
- @timesheet.stub!(:date_from)
25
- @timesheet.stub!(:date_from=)
26
- @timesheet.stub!(:date_to)
27
- @timesheet.stub!(:date_to=)
28
- @timesheet.stub!(:activities)
29
- @timesheet.stub!(:activities=)
30
- @timesheet.stub!(:users)
31
- @timesheet.stub!(:users=)
32
- @timesheet.stub!(:fetch_time_entries)
33
- @timesheet.stub!(:time_entries).and_return([ ])
34
- @timesheet.stub!(:sort)
35
- @timesheet.stub!(:sort=)
36
- @timesheet.stub!(:period_type=)
37
- stub_timesheet unless options[:skip_timesheet_stub]
38
- end
39
-
40
- # Converts current user to admin
41
- def mock_admin
42
- @current_user.stub!(:admin?).and_return(true)
43
- stub_current_user
44
- end
45
-
46
- # Restubs the current user
47
- def stub_current_user
48
- User.stub!(:current).and_return(@current_user)
49
- end
50
-
51
- # Restubs the new timesheet
52
- def stub_timesheet
53
- Timesheet.stub!(:new).and_return(@timesheet)
54
- end
55
- end
56
-
57
- describe 'TimesheetControllerShared', :shared => true do
58
- it 'should set @timesheet.allowed_projects to the list of current projects the user is a member of' do
59
- project1 = mock_model(Project)
60
- project2 = mock_model(Project)
61
- projects = [project1, project2]
62
-
63
- # Adjust mocks
64
- @user_project_mock.should_receive(:find).and_return(projects)
65
- stub_current_user
66
- @timesheet.should_receive(:allowed_projects=).with(projects)
67
- @timesheet.stub!(:allowed_projects).and_return(projects)
68
- stub_timesheet
69
-
70
- send_request
71
- assigns[:timesheet].allowed_projects.should eql(projects)
72
- end
73
-
74
- it 'should set @timesheet.allowed_projects to all the projects if the user is an admin' do
75
- mock_admin
76
- project1 = mock_model(Project)
77
- project2 = mock_model(Project)
78
- projects = [project1, project2]
79
-
80
- # Adjust mocks
81
- Project.stub!(:find).with(:all, { :order => "name ASC" }).and_return(projects)
82
- @timesheet.should_receive(:allowed_projects=).with(projects)
83
- @timesheet.stub!(:allowed_projects).and_return(projects)
84
- stub_timesheet
85
-
86
- send_request
87
- assigns[:timesheet].allowed_projects.should eql(projects)
88
- end
89
-
90
- it 'should get the list size from the settings' do
91
- settings = { 'list_size' => 10, 'precision' => '2' }
92
- Setting.should_receive(:plugin_timesheet_plugin).twice.and_return(settings)
93
-
94
- send_request
95
- assigns[:list_size].should eql(10)
96
- end
97
-
98
- it 'should get the precision from the settings' do
99
- settings = { 'list_size' => 10, 'precision' => '2' }
100
- Setting.should_receive(:plugin_timesheet_plugin).twice.and_return(settings)
101
-
102
- send_request
103
- assigns[:precision].should eql(2)
104
- end
105
-
106
- it 'should create a new @timesheet' do
107
- Timesheet.should_receive(:new).and_return(@timesheet)
108
-
109
- send_request
110
- assigns[:timesheet].should eql(@timesheet)
111
- end
112
- end
113
-
114
-
115
- describe TimesheetController do
116
- it "should use TimesheetController" do
117
- controller.should be_an_instance_of(TimesheetController)
118
- end
119
-
120
- end
121
- describe TimesheetController,"#index with GET request" do
122
- include TimesheetControllerHelper
123
-
124
- def send_request
125
- get 'index'
126
- end
127
-
128
- before(:each) do
129
- default_mocks
130
- end
131
-
132
- it_should_behave_like "TimesheetControllerShared"
133
-
134
- it 'should have no timelog entries' do
135
- get 'index'
136
- assigns[:timesheet].time_entries.should be_empty
137
- end
138
-
139
- it 'should render the index template' do
140
- get 'index'
141
- response.should render_template('index')
142
- end
143
- end
144
-
145
- describe TimesheetController,"#index with GET request and a session" do
146
- include TimesheetControllerHelper
147
- it 'should read the session data' do
148
- default_mocks(:skip_timesheet_stub => true)
149
-
150
- projects = []
151
- 4.times do |i|
152
- projects << mock_model(Project, :id => i + 1)
153
- end
154
-
155
- controller.stub!(:allowed_projects).and_return(projects)
156
- session[TimesheetController::SessionKey] = HashWithIndifferentAccess.new(
157
- :projects => projects.collect(&:id).collect(&:to_s),
158
- :date_to => '2009-01-01',
159
- :date_from => '2009-01-01'
160
- )
161
-
162
- get :index
163
- assigns[:timesheet].date_from.should eql('2009-01-01')
164
- assigns[:timesheet].date_to.should eql('2009-01-01')
165
- assigns[:timesheet].projects.should eql(projects)
166
- end
167
- end
168
-
169
- describe TimesheetController,"#index with GET request from an Anonymous user" do
170
- include TimesheetControllerHelper
171
-
172
- it 'should render the no_projects template' do
173
- get 'index'
174
- response.should render_template('no_projects')
175
- end
176
-
177
- end
178
-
179
- describe TimesheetController,"#report with GET request from an Anonymous user" do
180
- include TimesheetControllerHelper
181
-
182
- it 'should redirect to the index' do
183
- get 'report'
184
- response.should be_redirect
185
- response.should redirect_to(:action => 'index')
186
- end
187
-
188
- end
189
-
190
- describe TimesheetController,"#report with POST request from an Anonymous user" do
191
- include TimesheetControllerHelper
192
-
193
- it 'should redirect to the index' do
194
- get 'report'
195
- response.should be_redirect
196
- response.should redirect_to(:action => 'index')
197
- end
198
-
199
- end
200
-
201
- describe TimesheetController,"#report with POST request" do
202
- include TimesheetControllerHelper
203
-
204
- before(:each) do
205
- default_mocks
206
- end
207
-
208
- def send_request
209
- post_report
210
- end
211
-
212
- def post_report(data={ :timesheet => { } })
213
- post 'report', data
214
- end
215
-
216
- it_should_behave_like "TimesheetControllerShared"
217
-
218
- it 'should only allow the allowed projects into @timesheet.projects' do
219
- project1 = mock_model(Project, :to_param => '1', :id => 1)
220
- project2 = mock_model(Project, :to_param => '2', :id => 2)
221
- projects = [project1, project2]
222
-
223
- # Adjust mocks
224
- @user_project_mock.should_receive(:find).and_return(projects)
225
- stub_current_user
226
-
227
- @timesheet.should_receive(:allowed_projects=).with(projects)
228
- @timesheet.should_receive(:allowed_projects).twice.and_return(projects)
229
- @timesheet.should_receive(:projects=).with([project1])
230
- stub_timesheet
231
-
232
- post_report({ :timesheet => { :projects => ['1'] } })
233
- end
234
-
235
- it 'should save the session data' do
236
- post_report({ :timesheet => { :projects => ['1'] } })
237
- session[TimesheetController::SessionKey].should_not be_nil
238
- session[TimesheetController::SessionKey].keys.should include('projects')
239
- session[TimesheetController::SessionKey]['projects'].should eql(['1'])
240
- end
241
- end
242
-
243
- describe TimesheetController,"#report with request with no data" do
244
- include TimesheetControllerHelper
245
-
246
- before(:each) do
247
- default_mocks
248
- end
249
-
250
- describe 'should redirect to the index' do
251
- it 'from a GET request' do
252
- post 'report', { }
253
- response.should be_redirect
254
- response.should redirect_to(:action => 'index')
255
- end
256
-
257
- it 'from a POST request' do
258
- post 'report', { }
259
- response.should be_redirect
260
- response.should redirect_to(:action => 'index')
261
- end
262
- end
263
- end
@@ -1,537 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
-
3
- module TimesheetSpecHelper
4
- def timesheet_factory(options={ })
5
- timesheet = Timesheet.new(options)
6
- timesheet.date_from ||= Date.today.to_s
7
- timesheet.date_to ||= Date.today.to_s
8
-
9
- return timesheet
10
- end
11
-
12
- def project_factory(id, options = { })
13
- object_options = {
14
- :parent => nil,
15
- :id => id,
16
- :to_param => id.to_s
17
- }.merge(options)
18
-
19
- project = mock_model(Project, object_options)
20
- project_te1 = mock_model(TimeEntry, :id => '100' + id.to_s, :project_id => project.id, :issue_id => '1', :hours => '5', :activity_id => '1', :spent_on => Date.today, :user => 1)
21
- project_te2 = mock_model(TimeEntry, :id => '101' + id.to_s, :project_id => project.id, :issue_id => '1', :hours => '10', :activity_id => '1', :spent_on => Date.today, :user => 1)
22
- project_time_entries_mock = mock('project_time_entries_mock')
23
- project_time_entries_mock.stub!(:find).and_return([project_te1, project_te2])
24
- project.stub!(:time_entries).and_return(project_time_entries_mock)
25
- project.stub!(:name).and_return('Project ' + id.to_s)
26
-
27
- return project
28
- end
29
-
30
- def time_entry_factory(id, options = { })
31
- object_options = {
32
- :id => id,
33
- :to_param => id.to_s,
34
- :spent_on => Date.today,
35
- }.merge(options)
36
-
37
- time_entry = mock_model(TimeEntry, object_options)
38
- time_entry.stub!(:issue).and_return(options[:issue]) unless options[:issue].nil?
39
- return time_entry
40
- end
41
-
42
- def stub_non_member_user(projects)
43
- @current_user = mock_model(User)
44
- @current_user.stub!(:admin?).and_return(false)
45
- projects.each do |project|
46
- @current_user.stub!(:allowed_to?).with(:view_time_entries, project).and_return(false)
47
- @current_user.stub!(:allowed_to?).with(:see_project_timesheets, project).and_return(false)
48
- end
49
- User.stub!(:current).and_return(@current_user)
50
- end
51
-
52
- def stub_normal_user(projects)
53
- @current_user = mock_model(User)
54
- @current_user.stub!(:admin?).and_return(false)
55
- projects.each do |project|
56
- @current_user.stub!(:allowed_to?).with(:view_time_entries, project).and_return(true)
57
- @current_user.stub!(:allowed_to?).with(:see_project_timesheets, project).and_return(false)
58
- end
59
- User.stub!(:current).and_return(@current_user)
60
- end
61
-
62
- def stub_manager_user(projects)
63
- @current_user = mock_model(User)
64
- @current_user.stub!(:admin?).and_return(false)
65
- projects.each do |project|
66
- @current_user.stub!(:allowed_to?).with(:view_time_entries, project).and_return(true)
67
- @current_user.stub!(:allowed_to?).with(:see_project_timesheets, project).and_return(true)
68
- end
69
- User.stub!(:current).and_return(@current_user)
70
- end
71
-
72
- def stub_admin_user
73
- @current_user = mock_model(User)
74
- @current_user.stub!(:admin?).and_return(true)
75
- @current_user.stub!(:allowed_to?).and_return(true)
76
- @current_user.stub!(:name).and_return("Administrator Bob")
77
- User.stub!(:current).and_return(@current_user)
78
- end
79
- end
80
-
81
- describe Timesheet do
82
- it 'should not be an ActiveRecord class' do
83
- Timesheet.should_not be_a_kind_of(ActiveRecord::Base)
84
- end
85
- end
86
-
87
- describe Timesheet, 'initializing' do
88
- it 'should initialize time_entries to an empty Hash' do
89
- timesheet = Timesheet.new
90
- timesheet.time_entries.should be_a_kind_of(Hash)
91
- timesheet.time_entries.should be_empty
92
- end
93
-
94
- it 'should initialize projects to an empty Array' do
95
- timesheet = Timesheet.new
96
- timesheet.projects.should be_a_kind_of(Array)
97
- timesheet.projects.should be_empty
98
- end
99
-
100
- it 'should initialize allowed_projects to an empty Array' do
101
- timesheet = Timesheet.new
102
- timesheet.allowed_projects.should be_a_kind_of(Array)
103
- timesheet.allowed_projects.should be_empty
104
- end
105
-
106
- it 'should initialize activities to an Array' do
107
- timesheet = Timesheet.new
108
- timesheet.activities.should be_a_kind_of(Array)
109
- end
110
-
111
- it 'should initialize users to an Array' do
112
- timesheet = Timesheet.new
113
- timesheet.users.should be_a_kind_of(Array)
114
- end
115
-
116
- it 'should initialize sort to :project' do
117
- timesheet = Timesheet.new
118
- timesheet.sort.should eql(:project)
119
- end
120
-
121
- it 'should initialize time_entries to the passed in options' do
122
- data = { :test => true }
123
- timesheet = Timesheet.new({ :time_entries => data })
124
- timesheet.time_entries.should_not be_empty
125
- timesheet.time_entries.should eql(data)
126
- end
127
-
128
- it 'should initialize allowed_projects to the passed in options' do
129
- data = ['project1', 'project2']
130
- timesheet = Timesheet.new({ :allowed_projects => data })
131
- timesheet.allowed_projects.should_not be_empty
132
- timesheet.allowed_projects.should eql(data)
133
- end
134
-
135
- it 'should initialize activities to the integers of the passed in options' do
136
- act1 = mock('act1')
137
- act1.stub!(:to_i).and_return(200)
138
- act2 = mock('act2')
139
- act2.stub!(:to_i).and_return(300)
140
- data = [act1, act2]
141
- timesheet = Timesheet.new({ :activities => data })
142
- timesheet.activities.should_not be_empty
143
- timesheet.activities.should eql([200, 300])
144
- end
145
-
146
- it 'should initialize users to the ids of the passed in options' do
147
- user1 = mock('user1')
148
- user1.stub!(:to_i).and_return(100)
149
- user2 = mock('user2')
150
- user2.stub!(:to_i).and_return(101)
151
- data = [user1, user2]
152
- timesheet = Timesheet.new({ :users => data })
153
- timesheet.users.should_not be_empty
154
- timesheet.users.should eql([100, 101])
155
- end
156
-
157
- it 'should initialize sort to the :user option when passed :user' do
158
- timesheet = Timesheet.new({ :sort => :user })
159
- timesheet.sort.should eql(:user)
160
- end
161
-
162
- it 'should initialize sort to the :project option when passed :project' do
163
- timesheet = Timesheet.new({ :sort => :project })
164
- timesheet.sort.should eql(:project)
165
- end
166
-
167
- it 'should initialize sort to the :issue option when passed :issue' do
168
- timesheet = Timesheet.new({ :sort => :issue })
169
- timesheet.sort.should eql(:issue)
170
- end
171
-
172
- it 'should initialize sort to the :project option when passed an invalid sort' do
173
- timesheet = Timesheet.new({ :sort => :invalid })
174
- timesheet.sort.should eql(:project)
175
- end
176
- end
177
-
178
- describe Timesheet,'.fetch_time_entries' do
179
- include TimesheetSpecHelper
180
-
181
- it 'should clear .time_entries' do
182
- timesheet = Timesheet.new
183
- timesheet.time_entries = { :filled => 'data' }
184
- proc {
185
- timesheet.fetch_time_entries
186
- }.should change(timesheet, :time_entries)
187
-
188
- end
189
-
190
- it 'should add a time_entry Hash for each project' do
191
- timesheet = timesheet_factory
192
-
193
- project1 = project_factory(1)
194
- project2 = project_factory(2)
195
-
196
- stub_admin_user
197
- timesheet.projects = [project1, project2]
198
-
199
- timesheet.fetch_time_entries
200
- timesheet.time_entries.should_not be_empty
201
- timesheet.time_entries.should have(2).things
202
- end
203
-
204
- it 'should use the project name for each time_entry key' do
205
-
206
- timesheet = timesheet_factory
207
-
208
- project1 = project_factory(1)
209
- project1.should_receive(:name).and_return('Project 1')
210
- project2 = project_factory(2)
211
- project2.should_receive(:name).and_return('Project 2')
212
-
213
- stub_admin_user
214
- timesheet.projects = [project1, project2]
215
-
216
- timesheet.fetch_time_entries
217
- timesheet.time_entries.keys.should include("Project 1")
218
- timesheet.time_entries.keys.should include("Project 2")
219
- end
220
-
221
- it 'should add the parent project name for each time_entry array for sub-projects' do
222
- timesheet = timesheet_factory
223
-
224
- project1 = project_factory(1)
225
- project1.should_receive(:name).twice.and_return('Project 1')
226
- project2 = project_factory(2, :parent => project1 )
227
- project2.should_receive(:name).and_return('Project 2')
228
-
229
- stub_admin_user
230
- timesheet.projects = [project1, project2]
231
-
232
- timesheet.fetch_time_entries
233
- timesheet.time_entries.keys.should include("Project 1")
234
- timesheet.time_entries.keys.should include("Project 1 / Project 2")
235
- end
236
-
237
- it 'should fetch all the time entries on a project in the date range'
238
- it 'should fetch all the time entries on a project matching the activities'
239
- it 'should fetch all the time entries on a project matching the users'
240
- end
241
-
242
- describe Timesheet,'.fetch_time_entries with user sorting' do
243
- include TimesheetSpecHelper
244
-
245
- it 'should clear .time_entries' do
246
- timesheet = Timesheet.new({ :sort => :user })
247
- timesheet.time_entries = { :filled => 'data' }
248
- proc {
249
- timesheet.fetch_time_entries
250
- }.should change(timesheet, :time_entries)
251
-
252
- end
253
-
254
- it 'should add a time_entry array for each user' do
255
- stub_admin_user
256
- timesheet = timesheet_factory(:sort => :user, :users => [User.current.id])
257
-
258
- time_entries = [
259
- time_entry_factory(1, { :user => User.current }),
260
- time_entry_factory(2, { :user => User.current }),
261
- time_entry_factory(3, { :user => User.current }),
262
- time_entry_factory(4, { :user => User.current }),
263
- time_entry_factory(5, { :user => User.current })
264
- ]
265
-
266
- TimeEntry.stub!(:find).and_return(time_entries)
267
- User.stub!(:find_by_id).and_return(User.current)
268
-
269
- timesheet.fetch_time_entries
270
- timesheet.time_entries.should_not be_empty
271
- timesheet.time_entries.should have(1).thing # One user
272
- end
273
-
274
- it 'should use the user name for each time_entry array' do
275
- stub_admin_user
276
- timesheet = timesheet_factory(:sort => :user, :users => [User.current.id])
277
-
278
- time_entries = [
279
- time_entry_factory(1, { :user => User.current }),
280
- time_entry_factory(2, { :user => User.current }),
281
- time_entry_factory(3, { :user => User.current }),
282
- time_entry_factory(4, { :user => User.current }),
283
- time_entry_factory(5, { :user => User.current })
284
- ]
285
-
286
- TimeEntry.stub!(:find).and_return(time_entries)
287
- User.stub!(:find_by_id).and_return(User.current)
288
-
289
- timesheet.fetch_time_entries
290
- timesheet.time_entries.keys.should include("Administrator Bob")
291
- end
292
- end
293
-
294
- describe Timesheet,'.fetch_time_entries with issue sorting' do
295
- include TimesheetSpecHelper
296
-
297
- it 'should clear .time_entries' do
298
- timesheet = Timesheet.new({ :sort => :issue })
299
- timesheet.time_entries = { :filled => 'data' }
300
- proc {
301
- timesheet.fetch_time_entries
302
- }.should change(timesheet, :time_entries)
303
-
304
- end
305
-
306
- it 'should add a time_entry array for each project' do
307
- stub_admin_user
308
- project1 = project_factory(1)
309
- timesheet = timesheet_factory(:sort => :issue, :users => [User.current.id])
310
- timesheet.projects = [project1]
311
-
312
- @issue1 = mock_model(Issue, :id => 1, :to_param => '1', :project => project1)
313
- @issue2 = mock_model(Issue, :id => 1, :to_param => '1', :project => project1)
314
- @issue3 = mock_model(Issue, :id => 1, :to_param => '1', :project => project1)
315
-
316
- time_entry1 = time_entry_factory(1, { :user => User.current, :issue => @issue1 })
317
- time_entry2 = time_entry_factory(2, { :user => User.current, :issue => @issue1 })
318
- time_entry3 = time_entry_factory(3, { :user => User.current, :issue => @issue2 })
319
- time_entry4 = time_entry_factory(4, { :user => User.current, :issue => @issue2 })
320
- time_entry5 = time_entry_factory(5, { :user => User.current, :issue => @issue3 })
321
-
322
- project1.should_receive(:issues).and_return([@issue1, @issue2, @issue3])
323
-
324
- time_entries = [
325
- time_entry1,
326
- time_entry2,
327
- time_entry3,
328
- time_entry4,
329
- time_entry5
330
- ]
331
-
332
- timesheet.should_receive(:issue_time_entries_for_all_users).with(@issue1).and_return([time_entry1, time_entry2])
333
- timesheet.should_receive(:issue_time_entries_for_all_users).with(@issue2).and_return([time_entry3, time_entry4])
334
- timesheet.should_receive(:issue_time_entries_for_all_users).with(@issue3).and_return([time_entry5])
335
-
336
- timesheet.fetch_time_entries
337
- timesheet.time_entries.should_not be_empty
338
- timesheet.time_entries.should have(1).thing
339
- end
340
-
341
- it 'should use the project for each time_entry array' do
342
- stub_admin_user
343
- project1 = project_factory(1)
344
- timesheet = timesheet_factory(:sort => :issue, :users => [User.current.id])
345
- timesheet.projects = [project1]
346
-
347
- @issue1 = mock_model(Issue, :id => 1, :to_param => '1', :project => project1)
348
- @issue2 = mock_model(Issue, :id => 1, :to_param => '1', :project => project1)
349
- @issue3 = mock_model(Issue, :id => 1, :to_param => '1', :project => project1)
350
-
351
- time_entry1 = time_entry_factory(1, { :user => User.current, :issue => @issue1 })
352
- time_entry2 = time_entry_factory(2, { :user => User.current, :issue => @issue1 })
353
- time_entry3 = time_entry_factory(3, { :user => User.current, :issue => @issue2 })
354
- time_entry4 = time_entry_factory(4, { :user => User.current, :issue => @issue2 })
355
- time_entry5 = time_entry_factory(5, { :user => User.current, :issue => @issue3 })
356
-
357
- project1.should_receive(:issues).and_return([@issue1, @issue2, @issue3])
358
-
359
- time_entries = [
360
- time_entry1,
361
- time_entry2,
362
- time_entry3,
363
- time_entry4,
364
- time_entry5
365
- ]
366
-
367
- timesheet.should_receive(:issue_time_entries_for_all_users).with(@issue1).and_return([time_entry1, time_entry2])
368
- timesheet.should_receive(:issue_time_entries_for_all_users).with(@issue2).and_return([time_entry3, time_entry4])
369
- timesheet.should_receive(:issue_time_entries_for_all_users).with(@issue3).and_return([time_entry5])
370
-
371
- timesheet.fetch_time_entries
372
- timesheet.time_entries.keys.should include(project1)
373
- end
374
- end
375
-
376
- describe Timesheet,'.fetch_time_entries as an administrator' do
377
- include TimesheetSpecHelper
378
-
379
- it 'should collect time entries for all users on each project' do
380
- timesheet = timesheet_factory
381
-
382
- project1 = project_factory(1)
383
- project1.stub!(:name).and_return('Project 1')
384
- project2 = project_factory(2)
385
- project2.stub!(:name).and_return('Project 2')
386
-
387
- stub_admin_user
388
- timesheet.projects = [project1, project2]
389
-
390
- timesheet.should_receive(:time_entries_for_all_users).with(project1).and_return([ ])
391
- timesheet.should_receive(:time_entries_for_all_users).with(project2).and_return([ ])
392
- timesheet.fetch_time_entries
393
- end
394
- end
395
-
396
- describe Timesheet,'.fetch_time_entries as a user with see_project_timesheet permission on a project' do
397
- include TimesheetSpecHelper
398
-
399
- it 'should collect time entries for all users' do
400
- timesheet = timesheet_factory
401
-
402
- project1 = project_factory(1)
403
- project1.stub!(:name).and_return('Project 1')
404
- project2 = project_factory(2)
405
- project2.stub!(:name).and_return('Project 2')
406
- project3 = project_factory(3)
407
- project3.stub!(:name).and_return('Project 3')
408
-
409
- stub_manager_user([project1, project2])
410
- # Make user a 'non-manager' on project3
411
- @current_user.stub!(:allowed_to?).with(:view_time_entries, project3).and_return(true)
412
- @current_user.stub!(:allowed_to?).with(:see_project_timesheets, project3).and_return(false)
413
- User.stub!(:current).and_return(@current_user)
414
-
415
- timesheet.projects = [project1, project2, project3]
416
-
417
- timesheet.should_receive(:time_entries_for_all_users).with(project1).and_return([ ])
418
- timesheet.should_receive(:time_entries_for_all_users).with(project2).and_return([ ])
419
- timesheet.should_receive(:time_entries_for_current_user).with(project3).and_return([ ])
420
- timesheet.fetch_time_entries
421
- end
422
- end
423
-
424
- describe Timesheet,'.fetch_time_entries as a user with view_time_entries permission on a project' do
425
- include TimesheetSpecHelper
426
-
427
- it 'should collect time entries for only themself' do
428
- timesheet = timesheet_factory
429
-
430
- project1 = project_factory(1)
431
- project1.stub!(:name).and_return('Project 1')
432
- project2 = project_factory(2)
433
- project2.stub!(:name).and_return('Project 2')
434
-
435
- stub_normal_user([project1, project2])
436
- timesheet.projects = [project1, project2]
437
-
438
- timesheet.should_receive(:time_entries_for_current_user).with(project1).and_return([ ])
439
- timesheet.should_receive(:time_entries_for_current_user).with(project2).and_return([ ])
440
- timesheet.fetch_time_entries
441
- end
442
- end
443
-
444
- describe Timesheet,'.fetch_time_entries as a non-member of a project' do
445
- include TimesheetSpecHelper
446
-
447
- it 'should get no time entries' do
448
- timesheet = timesheet_factory
449
-
450
- project1 = project_factory(1)
451
- project1.stub!(:name).and_return('Project 1')
452
- project2 = project_factory(2)
453
- project2.stub!(:name).and_return('Project 2')
454
-
455
- stub_non_member_user([project1, project2])
456
- timesheet.projects = [project1, project2]
457
-
458
- timesheet.should_not_receive(:time_entries_for_current_user).with(project1).and_return([ ])
459
- timesheet.should_not_receive(:time_entries_for_current_user).with(project2).and_return([ ])
460
- timesheet.fetch_time_entries
461
- end
462
- end
463
-
464
- describe Timesheet, '#period=' do
465
- include TimesheetSpecHelper
466
- describe 'should set the date_to and date_from for' do
467
- before(:each) do
468
- @date = Date.new(2009,2,4)
469
- Date.stub!(:today).and_return(@date)
470
- @timesheet = Timesheet.new(:period_type => Timesheet::ValidPeriodType[:default])
471
- end
472
-
473
- it 'today' do
474
- @timesheet.should_receive(:date_from=).with(@date)
475
- @timesheet.should_receive(:date_to=).with(@date)
476
- @timesheet.period = 'today'
477
- end
478
-
479
- it 'yesterday' do
480
- @timesheet.should_receive(:date_from=).with(@date.yesterday)
481
- @timesheet.should_receive(:date_to=).with(@date.yesterday)
482
- @timesheet.period = 'yesterday'
483
- end
484
-
485
- it 'current_week' do
486
- @timesheet.should_receive(:date_from=).with(Date.new(2009, 2, 2))
487
- @timesheet.should_receive(:date_from).and_return(Date.new(2009, 2, 2))
488
- @timesheet.should_receive(:date_to=).with(Date.new(2009, 2, 8))
489
- @timesheet.period = 'current_week'
490
- end
491
-
492
- it 'last_week' do
493
- @timesheet.should_receive(:date_from=).with(Date.new(2009, 1, 26))
494
- @timesheet.should_receive(:date_from).and_return(Date.new(2009, 1, 26))
495
- @timesheet.should_receive(:date_to=).with(Date.new(2009, 2, 1))
496
- @timesheet.period = 'last_week'
497
- end
498
-
499
- it '7_days' do
500
- @timesheet.should_receive(:date_from=).with(@date - 7)
501
- @timesheet.should_receive(:date_to=).with(@date)
502
- @timesheet.period = '7_days'
503
- end
504
-
505
- it 'current_month' do
506
- @timesheet.should_receive(:date_from=).with(Date.new(2009, 2, 1))
507
- @timesheet.should_receive(:date_from).and_return(Date.new(2009, 2, 1))
508
- @timesheet.should_receive(:date_to=).with(Date.new(2009, 2, 28))
509
- @timesheet.period = 'current_month'
510
- end
511
-
512
- it 'last_month' do
513
- @timesheet.should_receive(:date_from=).with(Date.new(2009, 1, 1))
514
- @timesheet.should_receive(:date_from).and_return(Date.new(2009, 1, 1))
515
- @timesheet.should_receive(:date_to=).with(Date.new(2009, 1, 31))
516
- @timesheet.period = 'last_month'
517
- end
518
-
519
- it '30_days' do
520
- @timesheet.should_receive(:date_from=).with(@date - 30)
521
- @timesheet.should_receive(:date_to=).with(@date)
522
- @timesheet.period = '30_days'
523
- end
524
-
525
- it 'current_year' do
526
- @timesheet.should_receive(:date_from=).with(Date.new(2009,1,1))
527
- @timesheet.should_receive(:date_to=).with(Date.new(2009,12,31))
528
- @timesheet.period = 'current_year'
529
- end
530
-
531
- it 'all' do
532
- @timesheet.should_receive(:date_from=).with(nil)
533
- @timesheet.should_receive(:date_to=).with(nil)
534
- @timesheet.period = 'all'
535
- end
536
- end
537
- end