timesheet_plugin 0.5.0 → 0.6.0

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.
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