Project

General

Profile

Patch #1333 ยป 1195.diff

Mateo Murphy, 2008-05-30 21:26

View differences:

test/functional/projects_controller_test.rb (working copy)
23 23

  
24 24
class ProjectsControllerTest < Test::Unit::TestCase
25 25
  fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details,
26
           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
26
           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages, :membership_activities
27 27

  
28 28
  def setup
29 29
    @controller = ProjectsController.new
......
41 41
    assert assigns(:project_tree).has_key?(Project.find(1))
42 42
    # Subproject in corresponding value
43 43
    assert assigns(:project_tree)[Project.find(1)].include?(Project.find(3))
44
  end
45
  
46
  def test_show_by_id
47
    get :show, :id => 1
44
  end
45
  
46
  def test_show_by_id
47
    get :show, :id => 1
48 48
    assert_response :success
49
    assert_template 'show'
50
    assert_not_nil assigns(:project)
49
    assert_template 'show'
50
    assert_not_nil assigns(:project)
51 51
  end
52 52

  
53 53
  def test_show_by_identifier
......
95 95
    assert_response :success
96 96
    assert_template 'destroy'
97 97
    assert_not_nil Project.find_by_id(1)
98
  end
98
  end
99 99

  
100 100
  def test_post_destroy
101 101
    @request.session[:user_id] = 1 # admin
......
103 103
    assert_redirected_to 'admin/projects'
104 104
    assert_nil Project.find_by_id(1)
105 105
  end
106
  
107
  def test_list_files
108
    get :list_files, :id => 1
109
    assert_response :success
110
    assert_template 'list_files'
111
    assert_not_nil assigns(:versions)
112
  end
113

  
114
  def test_changelog
115
    get :changelog, :id => 1
116
    assert_response :success
117
    assert_template 'changelog'
118
    assert_not_nil assigns(:versions)
106
  
107
  def test_list_files
108
    get :list_files, :id => 1
109
    assert_response :success
110
    assert_template 'list_files'
111
    assert_not_nil assigns(:versions)
119 112
  end
113

  
114
  def test_changelog
115
    get :changelog, :id => 1
116
    assert_response :success
117
    assert_template 'changelog'
118
    assert_not_nil assigns(:versions)
119
  end
120 120
  
121 121
  def test_roadmap
122 122
    get :roadmap, :id => 1
......
178 178
               }
179 179
  end
180 180
  
181
  def test_membership_activity
182
    @request.session[:user_id] = 1 # admin
183
    get :activity, :id => 1, :from => '2006-08-09'
184
    assert_not_nil assigns(:events_by_day)
185
    
186
    ['Dave Lopper', 'Dave2 Lopper2', 'John Smith', 'John Smith'].each_with_index do |name, i|
187
      assert_select "dt:nth-of-type(#{i + 8}) a", name
188
    end
189
    
190
    assert_select "dt.member-destroy a", "Dave2 Lopper2"
191
    assert_select "dt.member-edit a", "Dave Lopper"
192

  
193
  end
194
  
181 195
  def test_activity_with_subprojects
182 196
    get :activity, :id => 1, :with_subprojects => 1
183 197
    assert_response :success
test/functional/users_controller_test.rb (working copy)
22 22
class UsersController; def rescue_action(e) raise e end; end
23 23

  
24 24
class UsersControllerTest < Test::Unit::TestCase
25
  fixtures :users, :projects, :members
25
  fixtures :users, :projects, :members, :membership_activities
26 26
  
27 27
  def setup
28 28
    @controller = UsersController.new
......
52 52
                           :membership => { :role_id => 2}
53 53
    assert_redirected_to 'users/edit/2'
54 54
    assert_equal 2, Member.find(1).role_id
55
    assert_equal 'edit', MembershipActivity.find(:first, :order => 'created_on DESC').action
55 56
  end
56 57
  
57 58
  def test_destroy_membership
58 59
    post :destroy_membership, :id => 2, :membership_id => 1
59 60
    assert_redirected_to 'users/edit/2'
60 61
    assert_nil Member.find_by_id(1)
62
    assert_equal 'destroy', MembershipActivity.find(:first, :order => 'created_on DESC').action    
61 63
  end
62 64
end
test/fixtures/membership_activities.yml (revision 0)
1
--- 
2
membership_activities_001: 
3
  id: 1
4
  project_id: 1  
5
  action: "new"
6
  user_id: 2
7
  creator_id: 1
8
  role_id: 1  
9
  created_on: 2006-07-19 19:35:33 +02:00
10

  
11
membership_activities_002: 
12
  id: 2  
13
  project_id: 1  
14
  action: "new"
15
  user_id: 3
16
  creator_id: 1
17
  role_id: 3
18
  created_on: 2006-07-19 19:35:36 +02:00
19

  
20
membership_activities_003: 
21
  id: 3
22
  project_id: 2
23
  action: "new"
24
  user_id: 2
25
  creator_id: 1        
26
  role_id: 2
27
  created_on: 2006-07-19 19:35:36 +02:00
28

  
29
membership_activities_004: 
30
  id: 4
31
  project_id: 1  
32
  action: "new"  
33
  user_id: 5
34
  creator_id: 1    
35
  role_id: 2
36
  created_on: 2006-07-19 19:35:36 +02:00  
37

  
38
membership_activities_005: 
39
  id: 5
40
  project_id: 5
41
  action: "new"  
42
  user_id: 2
43
  creator_id: 1    
44
  role_id: 1
45
  created_on: 2006-07-19 19:35:33 +02:00
46
  
47
membership_activities_006: 
48
  id: 6
49
  project_id: 1  
50
  action: "destroy"  
51
  user_id: 5
52
  creator_id: 1    
53
  role_id: 2
54
  created_on: 2006-07-19 20:35:36 +02:00  
55

  
56
membership_activities_007: 
57
  id: 7
58
  project_id: 1
59
  action: "edit"  
60
  user_id: 3
61
  creator_id: 1
62
  role_id: 2
63
  created_on: 2006-07-19 20:35:33 +02:00  
64
  
65
  
app/models/project.rb (working copy)
37 37
  has_one :repository, :dependent => :destroy
38 38
  has_many :changesets, :through => :repository
39 39
  has_one :wiki, :dependent => :destroy
40
  has_many :membership_activities, :dependent => :destroy
40 41
  # Custom field for the project issues
41 42
  has_and_belongs_to_many :custom_fields, 
42 43
                          :class_name => 'IssueCustomField',
......
180 181
  
181 182
  # Deletes all project's members
182 183
  def delete_all_members
184
    members.each do |m|
185
      MembershipActivity.create(
186
        :project_id => id,
187
        :action => 'destroy', 
188
        :user_id => m.user_id, 
189
        :creator_id => User.current.id, 
190
        :role_id => m.role_id
191
      )
192
    end
193
    
183 194
    Member.delete_all(['project_id = ?', id])
184 195
  end
185 196
  
app/models/membership_activity.rb (revision 0)
1
# redMine - project management software
2
# Copyright (C) 2006  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
class MembershipActivity < ActiveRecord::Base
19
  belongs_to :project
20
  belongs_to :user
21
  belongs_to :creator, :class_name => 'User', :foreign_key => 'creator_id'
22
  belongs_to :role
23

  
24
  acts_as_event :title => Proc.new {|o| "#{o.user.name}" },
25
                :description => Proc.new { |o| l(('text_' + o.action + '_member').to_sym, o.role.name) },
26
                :author => :creator,
27
                :type => Proc.new {|o| "member-#{o.action}" },
28
                :url => Proc.new {|o| {:controller => 'account', :action => 'show', :id => o.user.id} }
29
end
app/controllers/members_controller.rb (working copy)
20 20
  before_filter :find_member, :except => :new
21 21
  before_filter :find_project, :only => :new
22 22
  before_filter :authorize
23
  after_filter :log_activity
23 24

  
24 25
  def new
25
    @project.members << Member.new(params[:member]) if request.post?
26
    if request.post?
27
      @member = Member.new(params[:member])
28
      @project.members << @member
29
    end
30
    
26 31
    respond_to do |format|
27
      format.html { redirect_to :action => 'settings', :tab => 'members', :id => @project }
32
      format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
28 33
      format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
29 34
    end
30 35
  end
31 36
  
32 37
  def edit
33 38
    if request.post? and @member.update_attributes(params[:member])
34
  	 respond_to do |format|
39
  	  respond_to do |format|
35 40
        format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
36 41
        format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
37 42
      end
......
40 45

  
41 46
  def destroy
42 47
    @member.destroy
43
	respond_to do |format|
48
    respond_to do |format|
44 49
      format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
45 50
      format.js { render(:update) {|page| page.replace_html "tab-content-members", :partial => 'projects/settings/members'} }
46 51
    end
......
59 64
  rescue ActiveRecord::RecordNotFound
60 65
    render_404
61 66
  end
62
end
67
  
68
  def log_activity
69
    MembershipActivity.create(
70
      :project_id => @member.project_id, 
71
      :action => action_name, 
72
      :user_id => @member.user_id, 
73
      :creator_id => User.current.id, 
74
      :role_id => @member.role_id
75
    )
76
  end
77
  
78
end
app/controllers/users_controller.rb (working copy)
18 18
class UsersController < ApplicationController
19 19
  layout 'base'	
20 20
  before_filter :require_admin
21

  
21
  after_filter :log_activity, :only => [:edit_membership, :destroy_membership]
22
  
22 23
  helper :sort
23 24
  include SortHelper
24 25
  helper :custom_fields
......
104 105
  
105 106
  def destroy_membership
106 107
    @user = User.find(params[:id])
107
    Member.find(params[:membership_id]).destroy if request.post?
108
    if request.post?
109
      @membership = Member.find(params[:membership_id])
110
      @membership.destroy 
111
    end
108 112
    redirect_to :action => 'edit', :id => @user, :tab => 'memberships'
109 113
  end
114
  
115
private
116
  def log_activity
117
    action = action_name == 'destroy_membership' ? 'destroy' : params[:membership_id] ? 'edit' : 'new'
118
    
119
    MembershipActivity.create(
120
      :project_id => @membership.project_id, 
121
      :action => action, 
122
      :user_id => @membership.user_id, 
123
      :creator_id => User.current.id, 
124
      :role_id => @membership.role_id
125
    )
126
  end
127

  
110 128
end
app/controllers/projects_controller.rb (working copy)
237 237
    @date_to ||= Date.today + 1
238 238
    @date_from = @date_to - @days
239 239
    
240
    @event_types = %w(issues news files documents changesets wiki_pages messages)
240
    @event_types = %w(issues news files documents changesets wiki_pages messages membership_activity)
241 241
    if @project
242 242
      @event_types.delete('wiki_pages') unless @project.wiki
243 243
      @event_types.delete('changesets') unless @project.repository
......
316 316
      @events += Message.find(:all, :include => [{:board => :project}, :author], :conditions => cond.conditions)
317 317
    end
318 318
    
319
    if @scope.include?('membership_activity')
320
      cond = ARCondition.new(Project.allowed_to_condition(User.current, :manage_members, :project => @project, :with_subprojects => @with_subprojects))
321
      cond.add(["#{MembershipActivity.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to])
322
      @events += MembershipActivity.find(:all, :include => [:project, :user, :creator], :conditions => cond.conditions)
323
    end
324
    
319 325
    @events_by_day = @events.group_by(&:event_date)
320 326
    
321 327
    respond_to do |format|
lang/en.yml (working copy)
513 513
label_chronological_order: In chronological order
514 514
label_reverse_chronological_order: In reverse chronological order
515 515
label_planning: Planning
516
label_membership_activity_plural: Membership activity
516 517

  
517 518
button_login: Login
518 519
button_submit: Submit
......
596 597
text_destroy_time_entries: Delete reported hours
597 598
text_assign_time_entries_to_project: Assign reported hours to the project
598 599
text_reassign_time_entries: 'Reassign reported hours to this issue:'
600
text_new_member: "Was added as %s"
601
text_edit_member: "Changed roles to %s"
602
text_destroy_member: "Was removed from the project"
599 603
text_user_wrote: '%s wrote:'
600 604

  
601 605
default_role_manager: Manager
db/migrate/095_create_membership_activities.rb (revision 0)
1
class CreateMembershipActivities < ActiveRecord::Migration
2
  def self.up
3
    create_table :membership_activities do |t|
4
      t.column :project_id,   :integer
5
      t.column :action,       :string
6
      t.column :user_id,      :integer
7
      t.column :creator_id,   :integer
8
      t.column :role_id,      :integer
9
      t.column :created_on,   :datetime
10
    end
11
  end
12

  
13
  def self.down
14
    drop_table :membership_activities
15
  end
16
end
vendor/plugins/acts_as_event/lib/acts_as_event.rb (working copy)
64 64
        
65 65
        def event_url(options = {})
66 66
          option = event_options[:url]
67
          (option.is_a?(Proc) ? option.call(self) : send(option)).merge(options)
67
          if option.is_a?(Proc)
68
            option.call(self)
69
          elsif option.is_a?(Symbol)
70
            send(option)
71
          else
72
            option
73
          end.merge(options)
68 74
        end
69 75

  
70 76
        module ClassMethods
lib/redmine.rb (working copy)
21 21
  map.permission :select_project_modules, {:projects => :modules}, :require => :member
22 22
  map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy]}, :require => :member
23 23
  map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :destroy]}, :require => :member
24
  map.permission :view_membership_activity, {}
24 25
  
25 26
  map.project_module :issue_tracking do |map|
26 27
    # Issue categories
public/stylesheets/application.css (working copy)
194 194
dt.attachment { background-image: url(../images/attachment.png); }
195 195
dt.document { background-image: url(../images/document.png); }
196 196
dt.project { background-image: url(../images/projects.png); }
197
dt.member-new { background-image: url(../images/user_new.png); }
198
dt.member-edit { background-image: url(../images/user.png); }
199
dt.member-destroy { background-image: url(../images/false.png); }
197 200

  
201

  
198 202
div#roadmap fieldset.related-issues { margin-bottom: 1em; }
199 203
div#roadmap fieldset.related-issues ul { margin-top: 0.3em; margin-bottom: 0.3em; }
200 204
div#roadmap .wiki h1:first-child { display: none; }
    (1-1/1)