@@ -0,0 +1,56 | |||
|
1 | # Redmine - project management software | |
|
2 | # Copyright (C) 2006-2009 Jean-Philippe Lang | |
|
3 | # | |
|
4 | # This program is free software; you can redistribute it and/or | |
|
5 | # modify it under the terms of the GNU General Public License | |
|
6 | # as published by the Free Software Foundation; either version 2 | |
|
7 | # of the License, or (at your option) any later version. | |
|
8 | # | |
|
9 | # This program is distributed in the hope that it will be useful, | |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
|
12 | # GNU General Public License for more details. | |
|
13 | # | |
|
14 | # You should have received a copy of the GNU General Public License | |
|
15 | # along with this program; if not, write to the Free Software | |
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
|
17 | ||
|
18 | require File.dirname(__FILE__) + '/../../test_helper' | |
|
19 | ||
|
20 | class TimelogHelperTest < HelperTestCase | |
|
21 | include TimelogHelper | |
|
22 | include ActionView::Helpers::TextHelper | |
|
23 | include ActionView::Helpers::DateHelper | |
|
24 | ||
|
25 | fixtures :projects, :roles, :enabled_modules, :users, | |
|
26 | :repositories, :changesets, | |
|
27 | :trackers, :issue_statuses, :issues, :versions, :documents, | |
|
28 | :wikis, :wiki_pages, :wiki_contents, | |
|
29 | :boards, :messages, | |
|
30 | :attachments, | |
|
31 | :enumerations | |
|
32 | ||
|
33 | def setup | |
|
34 | super | |
|
35 | end | |
|
36 | ||
|
37 | def test_activities_collection_for_select_options_should_return_array_of_activity_names_and_ids | |
|
38 | activities = activity_collection_for_select_options | |
|
39 | assert activities.include?(["Design", 9]) | |
|
40 | assert activities.include?(["Development", 10]) | |
|
41 | end | |
|
42 | ||
|
43 | def test_activities_collection_for_select_options_should_not_include_inactive_activities | |
|
44 | activities = activity_collection_for_select_options | |
|
45 | assert !activities.include?(["Inactive Activity", 14]) | |
|
46 | end | |
|
47 | ||
|
48 | def test_activities_collection_for_select_options_should_use_the_projects_override | |
|
49 | project = Project.find(1) | |
|
50 | override_activity = TimeEntryActivity.create!({:name => "Design override", :parent => TimeEntryActivity.find_by_name("Design"), :project => project}) | |
|
51 | ||
|
52 | activities = activity_collection_for_select_options(nil, project) | |
|
53 | assert !activities.include?(["Design", 9]), "System activity found in: " + activities.inspect | |
|
54 | assert activities.include?(["Design override", override_activity.id]), "Override activity not found in: " + activities.inspect | |
|
55 | end | |
|
56 | end |
@@ -29,10 +29,16 module TimelogHelper | |||
|
29 | 29 | # Returns a collection of activities for a select field. time_entry |
|
30 | 30 | # is optional and will be used to check if the selected TimeEntryActivity |
|
31 | 31 | # is active. |
|
32 | def activity_collection_for_select_options(time_entry=nil) | |
|
33 | activities = TimeEntryActivity.active | |
|
32 | def activity_collection_for_select_options(time_entry=nil, project=nil) | |
|
33 | project ||= @project | |
|
34 | if project.nil? | |
|
35 | activities = TimeEntryActivity.active | |
|
36 | else | |
|
37 | activities = project.activities | |
|
38 | end | |
|
39 | ||
|
34 | 40 | collection = [] |
|
35 | if time_entry && !time_entry.activity.active? | |
|
41 | if time_entry && time_entry.activity && !time_entry.activity.active? | |
|
36 | 42 | collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] |
|
37 | 43 | else |
|
38 | 44 | collection << [ "--- #{l(:actionview_instancetag_blank_option)} ---", '' ] unless activities.detect(&:is_default) |
@@ -62,7 +62,7 class Enumeration < ActiveRecord::Base | |||
|
62 | 62 | |
|
63 | 63 | named_scope :active, lambda { |
|
64 | 64 | { |
|
65 | :conditions => {:active => true}, | |
|
65 | :conditions => {:active => true, :project_id => nil}, | |
|
66 | 66 | :order => 'position' |
|
67 | 67 | } |
|
68 | 68 | } |
@@ -20,6 +20,7 class Project < ActiveRecord::Base | |||
|
20 | 20 | STATUS_ACTIVE = 1 |
|
21 | 21 | STATUS_ARCHIVED = 9 |
|
22 | 22 | |
|
23 | has_many :time_entry_activities, :conditions => {:active => true } # Specific overidden Activities | |
|
23 | 24 | has_many :members, :include => :user, :conditions => "#{User.table_name}.type='User' AND #{User.table_name}.status=#{User::STATUS_ACTIVE}" |
|
24 | 25 | has_many :member_principals, :class_name => 'Member', |
|
25 | 26 | :include => :principal, |
@@ -155,6 +156,17 class Project < ActiveRecord::Base | |||
|
155 | 156 | statements.empty? ? base_statement : "((#{base_statement}) AND (#{statements.join(' OR ')}))" |
|
156 | 157 | end |
|
157 | 158 | |
|
159 | # Returns all the Systemwide and project specific activities | |
|
160 | def activities | |
|
161 | overridden_activity_ids = self.time_entry_activities.collect(&:parent_id) | |
|
162 | ||
|
163 | if overridden_activity_ids.empty? | |
|
164 | return TimeEntryActivity.active | |
|
165 | else | |
|
166 | return system_activities_and_project_overrides | |
|
167 | end | |
|
168 | end | |
|
169 | ||
|
158 | 170 | # Returns a :conditions SQL string that can be used to find the issues associated with this project. |
|
159 | 171 | # |
|
160 | 172 | # Examples: |
@@ -446,4 +458,12 private | |||
|
446 | 458 | def allowed_actions |
|
447 | 459 | @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten |
|
448 | 460 | end |
|
461 | ||
|
462 | # Returns the systemwide activities merged with the project specific overrides | |
|
463 | def system_activities_and_project_overrides | |
|
464 | return TimeEntryActivity.active. | |
|
465 | find(:all, | |
|
466 | :conditions => ["id NOT IN (?)", self.time_entry_activities.collect(&:parent_id)]) + | |
|
467 | self.time_entry_activities | |
|
468 | end | |
|
449 | 469 | end |
@@ -313,6 +313,53 class ProjectTest < ActiveSupport::TestCase | |||
|
313 | 313 | assert_equal 1, copied_project.status |
|
314 | 314 | end |
|
315 | 315 | |
|
316 | def test_activities_should_use_the_system_activities | |
|
317 | project = Project.find(1) | |
|
318 | assert_equal project.activities, TimeEntryActivity.find(:all, :conditions => {:active => true} ) | |
|
319 | end | |
|
320 | ||
|
321 | ||
|
322 | def test_activities_should_use_the_project_specific_activities | |
|
323 | project = Project.find(1) | |
|
324 | overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project}) | |
|
325 | assert overridden_activity.save! | |
|
326 | ||
|
327 | assert project.activities.include?(overridden_activity), "Project specific Activity not found" | |
|
328 | end | |
|
329 | ||
|
330 | def test_activities_should_not_include_the_inactive_project_specific_activities | |
|
331 | project = Project.find(1) | |
|
332 | overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => TimeEntryActivity.find(:first), :active => false}) | |
|
333 | assert overridden_activity.save! | |
|
334 | ||
|
335 | assert !project.activities.include?(overridden_activity), "Inactive Project specific Activity found" | |
|
336 | end | |
|
337 | ||
|
338 | def test_activities_should_not_include_project_specific_activities_from_other_projects | |
|
339 | project = Project.find(1) | |
|
340 | overridden_activity = TimeEntryActivity.new({:name => "Project", :project => Project.find(2)}) | |
|
341 | assert overridden_activity.save! | |
|
342 | ||
|
343 | assert !project.activities.include?(overridden_activity), "Project specific Activity found on a different project" | |
|
344 | end | |
|
345 | ||
|
346 | def test_activities_should_handle_nils | |
|
347 | TimeEntryActivity.delete_all | |
|
348 | ||
|
349 | project = Project.find(1) | |
|
350 | assert project.activities.empty? | |
|
351 | end | |
|
352 | ||
|
353 | def test_activities_should_override_system_activities_with_project_activities | |
|
354 | project = Project.find(1) | |
|
355 | parent_activity = TimeEntryActivity.find(:first) | |
|
356 | overridden_activity = TimeEntryActivity.new({:name => "Project", :project => project, :parent => parent_activity}) | |
|
357 | assert overridden_activity.save! | |
|
358 | ||
|
359 | assert project.activities.include?(overridden_activity), "Project specific Activity not found" | |
|
360 | assert !project.activities.include?(parent_activity), "System Activity found when it should have been overridden" | |
|
361 | end | |
|
362 | ||
|
316 | 363 | context "Project#copy" do |
|
317 | 364 | setup do |
|
318 | 365 | ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests |
General Comments 0
You need to be logged in to leave comments.
Login now