Project

General

Profile

« Previous | Next » 

Revision 549

Added the ability to archive projects:
  • Only administrators can archive/unarchive projects.
  • Once archived, the project is visible on the admin project listing only. It doesn't show up anywhere else in the app. Subprojects are also archived.
  • Archive/unarchive preserve everything on the project (issues, members, ...).
  • A subproject can not be unarchived if its parent project is archived.

View differences:

trunk/app/controllers/admin_controller.rb
27 27
	
28 28
  def projects
29 29
    sort_init 'name', 'asc'
30
    sort_update		
31
    @project_count = Project.count		
30
    sort_update
31
    
32
    @status = params[:status] ? params[:status].to_i : 0
33
    conditions = nil
34
    conditions = ["status=?", @status] unless @status == 0
35
    
36
    @project_count = Project.count(:conditions => conditions)
32 37
    @project_pages = Paginator.new self, @project_count,
33
								15,
38
								25,
34 39
								params['page']								
35 40
    @projects = Project.find :all, :order => sort_clause,
41
                        :conditions => conditions,
36 42
						:limit  =>  @project_pages.items_per_page,
37 43
						:offset =>  @project_pages.current.offset
38 44

  
trunk/app/controllers/application.rb
86 86

  
87 87
  # authorizes the user for the requested action.
88 88
  def authorize(ctrl = params[:controller], action = params[:action])
89
    unless @project.active?
90
      @project = nil
91
      render_404
92
      return false
93
    end
89 94
    # check if action is allowed on public projects
90 95
    if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ ctrl, action ]
91 96
      return true
......
105 110
  # make sure that the user is a member of the project (or admin) if project is private
106 111
  # used as a before_filter for actions that do not require any particular permission on the project
107 112
  def check_project_privacy
113
    unless @project.active?
114
      @project = nil
115
      render_404
116
      return false
117
    end
108 118
    return true if @project.is_public?
109 119
    return false unless logged_in_user
110 120
    return true if logged_in_user.admin? || logged_in_user_membership
trunk/app/controllers/projects_controller.rb
19 19

  
20 20
class ProjectsController < ApplicationController
21 21
  layout 'base'
22
  before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
23
  before_filter :require_admin, :only => [ :add, :destroy ]
22
  before_filter :find_project, :except => [ :index, :list, :add ]
23
  before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy ]
24
  before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ]
24 25
  
26
  cache_sweeper :project_sweeper, :only => [ :add, :edit, :archive, :unarchive, :destroy ]
25 27
  cache_sweeper :issue_sweeper, :only => [ :add_issue ]
26 28

  
27 29
  helper :sort
......
86 88
  def show
87 89
    @custom_values = @project.custom_values.find(:all, :include => :custom_field)
88 90
    @members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
89
    @subprojects = @project.children if @project.children.size > 0
91
    @subprojects = @project.active_children
90 92
    @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
91 93
    @trackers = Tracker.find(:all, :order => 'position')
92 94
    @open_issues_by_tracker = Issue.count(:group => :tracker, :joins => "INNER JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{Issue.table_name}.status_id", :conditions => ["project_id=? and #{IssueStatus.table_name}.is_closed=?", @project.id, false])
......
138 140
    end
139 141
  end
140 142

  
143
  def archive
144
    @project.archive if request.post? && @project.active?
145
    redirect_to :controller => 'admin', :action => 'projects'
146
  end
147
  
148
  def unarchive
149
    @project.unarchive if request.post? && [email protected]?
150
    redirect_to :controller => 'admin', :action => 'projects'
151
  end
152
  
141 153
  # Delete @project
142 154
  def destroy
155
    @project_to_destroy = @project
143 156
    if request.post? and params[:confirm]
144
      @project.destroy
157
      @project_to_destroy.destroy
145 158
      redirect_to :controller => 'admin', :action => 'projects'
146 159
    end
160
    # hide project in layout
161
    @project = nil
147 162
  end
148 163
	
149 164
  # Add a new issue category to @project
trunk/app/controllers/reports_controller.rb
55 55
      render :template => "reports/issue_report_details"  
56 56
    when "subproject"
57 57
      @field = "project_id"
58
      @rows = @project.children
58
      @rows = @project.active_children
59 59
      @data = issues_by_subproject
60 60
      @report_title = l(:field_subproject)
61 61
      render :template => "reports/issue_report_details"  
......
66 66
      @priorities = Enumeration::get_values('IPRI')
67 67
      @categories = @project.issue_categories
68 68
      @authors = @project.members.collect { |m| m.user }
69
      @subprojects = @project.children
69
      @subprojects = @project.active_children
70 70
      issues_by_tracker
71 71
      issues_by_version
72 72
      issues_by_priority
......
207 207
                                                  #{Issue.table_name} i, #{IssueStatus.table_name} s
208 208
                                                where 
209 209
                                                  i.status_id=s.id 
210
                                                  and i.project_id IN (#{@project.children.collect{|p| p.id}.join(',')})
211
                                                group by s.id, s.is_closed, i.project_id") if @project.children.any?
210
                                                  and i.project_id IN (#{@project.active_children.collect{|p| p.id}.join(',')})
211
                                                group by s.id, s.is_closed, i.project_id") if @project.active_children.any?
212 212
    @issues_by_subproject ||= []
213 213
  end
214 214
end
trunk/app/controllers/users_controller.rb
88 88
    end
89 89
    @auth_sources = AuthSource.find(:all)
90 90
    @roles = Role.find(:all, :order => 'position')
91
    @projects = Project.find(:all) - @user.projects
91
    @projects = Project.find(:all, :order => 'name', :conditions => "status=#{Project::STATUS_ACTIVE}") - @user.projects
92 92
    @membership ||= Member.new
93 93
  end
94 94
  
trunk/app/helpers/admin_helper.rb
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
module AdminHelper
19
  def project_status_options_for_select(selected)
20
    options_for_select([[l(:label_all), "*"], 
21
                        [l(:status_active), 1]], selected)
22
  end
19 23
end
trunk/app/models/project.rb
16 16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 17

  
18 18
class Project < ActiveRecord::Base
19
  # Project statuses
20
  STATUS_ACTIVE     = 1
21
  STATUS_ARCHIVED   = 9
22
  
19 23
  has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
20 24
  has_many :members, :dependent => :delete_all, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
21 25
  has_many :users, :through => :members
......
32 36
  has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
33 37
  acts_as_tree :order => "name", :counter_cache => true
34 38
  
39
  attr_protected :status
40
  
35 41
  validates_presence_of :name, :description, :identifier
36 42
  validates_uniqueness_of :name, :identifier
37 43
  validates_associated :custom_values, :on => :update
......
52 58
  
53 59
  def issues_with_subprojects(include_subprojects=false)
54 60
    conditions = nil
55
    if include_subprojects && children.size > 0
56
      ids = [id] + children.collect {|c| c.id}
61
    if include_subprojects && !active_children.empty?
62
      ids = [id] + active_children.collect {|c| c.id}
57 63
      conditions = ["#{Issue.table_name}.project_id IN (#{ids.join(',')})"]
58
    else
59
      conditions = ["#{Issue.table_name}.project_id = ?", id]
60 64
    end
65
    conditions ||= ["#{Issue.table_name}.project_id = ?", id]
61 66
    Issue.with_scope :find => { :conditions => conditions } do 
62 67
      yield
63 68
    end 
......
71 76

  
72 77
  def self.visible_by(user=nil)
73 78
    if user && user.admin?
74
      return nil
79
      return ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"]
75 80
    elsif user && !user.memberships.empty?
76
      return ["#{Project.table_name}.is_public = ? or #{Project.table_name}.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')})", true]
81
      return ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND (#{Project.table_name}.is_public = ? or #{Project.table_name}.id IN (#{user.memberships.collect{|m| m.project_id}.join(',')}))", true]
77 82
    else
78
      return ["#{Project.table_name}.is_public = ?", true]
83
      return ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE} AND #{Project.table_name}.is_public = ?", true]
79 84
    end
80 85
  end
81 86
  
87
  def active?
88
    self.status == STATUS_ACTIVE
89
  end
90
  
91
  def archive
92
    # Archive subprojects if any
93
    children.each do |subproject|
94
      subproject.archive
95
    end
96
    update_attribute :status, STATUS_ARCHIVED
97
  end
98
  
99
  def unarchive
100
    return false if parent && !parent.active?
101
    update_attribute :status, STATUS_ACTIVE
102
  end
103
  
104
  def active_children
105
    children.select {|child| child.active?}
106
  end
107
  
82 108
  # Returns an array of all custom fields enabled for project issues
83 109
  # (explictly associated custom fields and custom fields enabled for all projects)
84 110
  def custom_fields_for_issues(tracker)
trunk/app/models/query.rb
95 95
      @available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values }  
96 96
      @available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
97 97
      @available_filters["fixed_version_id"] = { :type => :list_optional, :order => 7, :values => @project.versions.sort.collect{|s| [s.name, s.id.to_s] } }
98
      unless @project.children.empty?
99
        @available_filters["subproject_id"] = { :type => :list_one_or_more, :order => 13, :values => @project.children.collect{|s| [s.name, s.id.to_s] } }
98
      unless @project.active_children.empty?
99
        @available_filters["subproject_id"] = { :type => :list_one_or_more, :order => 13, :values => @project.active_children.collect{|s| [s.name, s.id.to_s] } }
100 100
      end
101 101
      @project.all_custom_fields.select(&:is_filter?).each do |field|
102 102
        case field.field_format
......
164 164
      if operator_for("subproject_id") == "="
165 165
        subproject_ids = values_for("subproject_id").each(&:to_i)
166 166
      else
167
        subproject_ids = project.children.collect{|p| p.id}
167
        subproject_ids = project.active_children.collect{|p| p.id}
168 168
      end
169 169
      sql << " AND #{Issue.table_name}.project_id IN (%d,%s)" % [project.id, subproject_ids.join(",")] if project
170 170
    else
trunk/app/models/user.rb
23 23
  STATUS_REGISTERED = 2
24 24
  STATUS_LOCKED     = 3
25 25

  
26
  has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :order => "#{Project.table_name}.name", :dependent => :delete_all
26
  has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name", :dependent => :delete_all
27 27
  has_many :projects, :through => :memberships
28 28
  has_many :custom_values, :dependent => :delete_all, :as => :customized
29 29
  has_one :preference, :dependent => :destroy, :class_name => 'UserPreference'
trunk/app/sweepers/project_sweeper.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  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 ProjectSweeper < ActionController::Caching::Sweeper
19
  observe Project
20

  
21
  def before_save(project)
22
    if project.new_record?
23
      expire_cache_for(project.parent) if project.parent
24
    else
25
      project_before_update = Project.find(project.id)
26
      return if project_before_update.parent_id == project.parent_id && project_before_update.status == project.status
27
      expire_cache_for(project.parent) if project.parent      
28
      expire_cache_for(project_before_update.parent) if project_before_update.parent
29
    end
30
  end
31
  
32
  def after_destroy(project)
33
    expire_cache_for(project.parent) if project.parent
34
  end
35
          
36
private
37
  def expire_cache_for(project)
38
    expire_fragment(Regexp.new("projects/(calendar|gantt)/#{project.id}\\."))
39
  end
40
end
trunk/app/views/admin/projects.rhtml
4 4

  
5 5
<h2><%=l(:label_project_plural)%></h2>
6 6

  
7
<% form_tag() do %>
8
<fieldset><legend><%= l(:label_filter_plural) %></legend>
9
<label><%= l(:field_status) %> :</label>
10
<%= select_tag 'status', project_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;"  %>
11
<%= submit_tag l(:button_apply), :class => "small" %>
12
</fieldset>
13
<% end %>
14
&nbsp;
15

  
7 16
<table class="list">
8 17
  <thead><tr>
9 18
	<%= sort_header_tag('name', :caption => l(:label_project)) %>
......
12 21
	<th><%=l(:label_subproject_plural)%></th>
13 22
	<%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
14 23
    <th></th>
24
    <th></th>
15 25
  </tr></thead>
16 26
  <tbody>
17 27
<% for project in @projects %>
18 28
  <tr class="<%= cycle("odd", "even") %>">
19
	<td><%= link_to project.name, :controller => 'projects', :action => 'settings', :id => project %>
29
	<td><%= project.active? ? link_to(project.name, :controller => 'projects', :action => 'settings', :id => project) : h(project.name) %>
20 30
	<td><%=h project.description %>
21 31
	<td align="center"><%= image_tag 'true.png' if project.is_public? %>
22 32
	<td align="center"><%= project.children.size %>
23 33
	<td align="center"><%= format_date(project.created_on) %>
24
  <td align="center">
25
    <%= button_to l(:button_delete), { :controller => 'projects', :action => 'destroy', :id => project }, :class => "button-small" %>
34
  <td align="center" style="width:10%">
35
    <small>
36
    <%= link_to(l(:button_archive), { :controller => 'projects', :action => 'archive', :id => project }, :method => :post, :class => 'icon icon-lock') if project.active? %>
37
    <%= link_to(l(:button_unarchive), { :controller => 'projects', :action => 'unarchive', :id => project }, :method => :post, :class => 'icon icon-unlock') if !project.active? && (project.parent.nil? || project.parent.active?) %>
38
    </small>
26 39
  </td>
40
  <td align="center" style="width:10%">
41
    <small><%= link_to(l(:button_delete), { :controller => 'projects', :action => 'destroy', :id => project }, :class => 'icon icon-del') %></small>
42
  </td>
27 43
  </tr>
28 44
<% end %>
29 45
  </tbody>
30 46
</table>
31 47

  
32
<p><%= pagination_links_full @project_pages %>
33
[ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p>
48
<p><%= pagination_links_full @project_pages, :status => @status %>
49
[ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p>
trunk/app/views/my/blocks/_issuesassignedtome.rhtml
1 1
<h3><%=l(:label_assigned_to_me_issues)%></h3>
2 2
<% assigned_issues = Issue.find(:all, 
3
                                :conditions => ["assigned_to_id=? AND #{IssueStatus.table_name}.is_closed=?", user.id, false],
3
                                :conditions => ["assigned_to_id=? AND #{IssueStatus.table_name}.is_closed=? AND #{Project.table_name}.status=#{Project::STATUS_ACTIVE}", user.id, false],
4 4
                                :limit => 10, 
5 5
                                :include => [ :status, :project, :tracker ], 
6 6
                                :order => "#{Issue.table_name}.updated_on DESC") %>
trunk/app/views/my/blocks/_issuesreportedbyme.rhtml
1 1
<h3><%=l(:label_reported_issues)%></h3>
2 2
<% reported_issues = Issue.find(:all, 
3
                                :conditions => ["author_id=?", user.id],
3
                                :conditions => ["author_id=? AND #{Project.table_name}.status=#{Project::STATUS_ACTIVE}", user.id],
4 4
                                :limit => 10, 
5 5
                                :include => [ :status, :project, :tracker ], 
6 6
                                :order => "#{Issue.table_name}.updated_on DESC") %>
trunk/app/views/my/blocks/_issueswatched.rhtml
2 2
<% watched_issues = Issue.find(:all, 
3 3
                               :include => [:status, :project, :tracker, :watchers],
4 4
                               :limit => 10, 
5
                               :conditions => ["#{Watcher.table_name}.user_id = ?", user.id],
5
                               :conditions => ["#{Watcher.table_name}.user_id = ? AND #{Project.table_name}.status=#{Project::STATUS_ACTIVE}", user.id],
6 6
                               :order => "#{Issue.table_name}.updated_on DESC") %>
7 7
<%= render :partial => 'issues/list_simple', :locals => { :issues => watched_issues } %>
8 8
<% if watched_issues.length > 0 %>
trunk/app/views/projects/calendar.rhtml
23 23
      <%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s) %>
24 24
      <%= tracker.name %><br />
25 25
    <% end %>
26
    <% if @project.children.any? %>
26
    <% if @project.active_children.any? %>
27 27
    <p><strong><%=l(:label_subproject_plural)%></strong></p>
28 28
    <%= check_box_tag "with_subprojects", 1, params[:with_subprojects] %> <%= l(:general_text_Yes) %>
29 29
    <% end %>
trunk/app/views/projects/destroy.rhtml
1 1
<h2><%=l(:label_confirmation)%></h2>
2 2
<div class="box">
3 3
<center>
4
<p><strong><%= @project.name %></strong><br />
4
<p><strong><%= @project_to_destroy.name %></strong><br />
5 5
<%=l(:text_project_destroy_confirmation)%></p>
6 6

  
7 7
<p>
8
    <% form_tag({:controller => 'projects', :action => 'destroy', :id => @project}) do %>
8
    <% form_tag({:controller => 'projects', :action => 'destroy', :id => @project_to_destroy}) do %>
9 9
    <%= hidden_field_tag "confirm", 1 %>
10 10
    <%= submit_tag l(:button_delete) %>
11 11
    <% end %>
trunk/app/views/projects/gantt.rhtml
49 49
      <%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s) %>
50 50
      <%= tracker.name %><br />
51 51
    <% end %>
52
    <% if @project.children.any? %>
52
    <% if @project.active_children.any? %>
53 53
    <p><strong><%=l(:label_subproject_plural)%></strong></p>
54 54
    <%= check_box_tag "with_subprojects", 1, params[:with_subprojects] %> <%= l(:general_text_Yes) %>
55 55
    <% end %>
trunk/app/views/projects/show.rhtml
45 45
		<% end %>		
46 46
	</div>
47 47
  
48
  <% if @subprojects %>
48
  <% if @subprojects.any? %>
49 49
 	<div class="box">
50 50
		<h3 class="icon22 icon22-projects"><%=l(:label_subproject_plural)%></h3>	
51 51
		<%= @subprojects.collect{|p| link_to(p.name, :action => 'show', :id => p)}.join(", ") %>
trunk/db/migrate/051_add_project_status.rb
1
class AddProjectStatus < ActiveRecord::Migration
2
  def self.up
3
    add_column :projects, :status, :integer, :default => 1, :null => false
4
  end
5

  
6
  def self.down
7
    remove_column :projects, :status
8
  end
9
end
trunk/lang/bg.yml
425 425
button_watch: Наблюдавай
426 426
button_unwatch: Спри наблюдението
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: активен
430 432
status_registered: регистриран
trunk/lang/de.yml
425 425
button_watch: Watch
426 426
button_unwatch: Unwatch
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: aktiv
430 432
status_registered: angemeldet
trunk/lang/en.yml
425 425
button_watch: Watch
426 426
button_unwatch: Unwatch
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: active
430 432
status_registered: registered
trunk/lang/es.yml
425 425
button_watch: Watch
426 426
button_unwatch: Unwatch
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: active
430 432
status_registered: registered
trunk/lang/fr.yml
425 425
button_watch: Surveiller
426 426
button_unwatch: Ne plus surveiller
427 427
button_reply: Répondre
428
button_archive: Archiver
429
button_unarchive: Désarchiver
428 430

  
429 431
status_active: actif
430 432
status_registered: enregistré
trunk/lang/it.yml
425 425
button_watch: Watch
426 426
button_unwatch: Unwatch
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: attivo
430 432
status_registered: registrato
trunk/lang/ja.yml
426 426
button_watch: Watch
427 427
button_unwatch: Unwatch
428 428
button_reply: Reply
429
button_archive: Archive
430
button_unarchive: Unarchive
429 431

  
430 432
status_active: 有効
431 433
status_registered: 登録
trunk/lang/nl.yml
425 425
button_watch: Monitor
426 426
button_unwatch: Niet meer monitoren
427 427
button_reply: Antwoord
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: Actief
430 432
status_registered: geregistreerd
trunk/lang/pt-br.yml
425 425
button_watch: Watch
426 426
button_unwatch: Unwatch
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: ativo
430 432
status_registered: registrado
trunk/lang/pt.yml
425 425
button_watch: Observar
426 426
button_unwatch: Não observar
427 427
button_reply: Reply
428
button_archive: Archive
429
button_unarchive: Unarchive
428 430

  
429 431
status_active: ativo
430 432
status_registered: registrado
trunk/lang/zh.yml
428 428
button_watch: Watch
429 429
button_unwatch: Unwatch
430 430
button_reply: Reply
431
button_archive: Archive
432
button_unarchive: Unarchive
431 433

  
432 434
status_active: 激活
433 435
status_registered: 已注册
trunk/public/stylesheets/application.css
163 163
.icon-fav  { background-image: url(../images/fav.png); }
164 164
.icon-fav-off  { background-image: url(../images/fav_off.png); }
165 165
.icon-reload  { background-image: url(../images/reload.png); }
166
.icon-lock  { background-image: url(../images/locked.png); }
167
.icon-unlock  { background-image: url(../images/unlock.png); }
166 168

  
167 169
.icon22-projects { background-image: url(../images/22x22/projects.png); }
168 170
.icon22-users { background-image: url(../images/22x22/users.png); }
trunk/test/functional/projects_controller_test.rb
1 1
# redMine - project management software
2
# Copyright (C) 2006  Jean-Philippe Lang
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3 3
#
4 4
# This program is free software; you can redistribute it and/or
5 5
# modify it under the terms of the GNU General Public License
......
125 125
    assert_template 'activity'
126 126
    assert_not_nil assigns(:events_by_day)
127 127
  end
128
  
129
  def test_archive    
130
    @request.session[:user_id] = 1 # admin
131
    post :archive, :id => 1
132
    assert_redirected_to 'admin/projects'
133
    assert !Project.find(1).active?
134
  end
135
  
136
  def test_unarchive
137
    @request.session[:user_id] = 1 # admin
138
    Project.find(1).archive
139
    post :unarchive, :id => 1
140
    assert_redirected_to 'admin/projects'
141
    assert Project.find(1).active?
142
  end
128 143
end
trunk/test/integration/projects_test.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  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 ProjectsTest < ActionController::IntegrationTest
21
  fixtures :projects, :users, :members
22
  
23
  def test_archive_project
24
    subproject = Project.find(1).children.first
25
    log_user("admin", "admin")
26
    get "admin/projects"
27
    assert_response :success
28
    assert_template "admin/projects"
29
    post "projects/archive", :id => 1
30
    assert_redirected_to "admin/projects"    
31
    assert !Project.find(1).active?
32
    
33
    get "projects/show", :id => 1
34
    assert_response :missing
35
    get "projects/show", :id => subproject.id
36
    assert_response :missing
37
    
38
    post "projects/unarchive", :id => 1
39
    assert_redirected_to "admin/projects"    
40
    assert Project.find(1).active?
41
    get "projects/show", :id => 1
42
    assert_response :success
43
  end  
44
end
0 45

  
trunk/test/unit/project_test.rb
1 1
# redMine - project management software
2
# Copyright (C) 2006  Jean-Philippe Lang
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3 3
#
4 4
# This program is free software; you can redistribute it and/or
5 5
# modify it under the terms of the GNU General Public License
......
51 51
    assert_equal true, public_projects[0].is_public?
52 52
  end
53 53
  
54
  def test_archive
55
    user = @ecookbook.members.first.user
56
    @ecookbook.archive
57
    @ecookbook.reload
58
    
59
    assert [email protected]?
60
    assert !user.projects.include?(@ecookbook)
61
    # Subproject are also archived
62
    assert [email protected]?
63
    assert @ecookbook.active_children.empty?
64
  end
65
  
66
  def test_unarchive
67
    user = @ecookbook.members.first.user
68
    @ecookbook.archive
69
    # A subproject of an archived project can not be unarchived
70
    assert !@ecookbook_sub1.unarchive
71
    
72
    # Unarchive project
73
    assert @ecookbook.unarchive
74
    @ecookbook.reload
75
    assert @ecookbook.active?
76
    assert user.projects.include?(@ecookbook)
77
    # Subproject can now be unarchived
78
    @ecookbook_sub1.reload
79
    assert @ecookbook_sub1.unarchive
80
  end
81
  
54 82
  def test_destroy
55 83
    @ecookbook.destroy
56 84
    assert_raise(ActiveRecord::RecordNotFound) { Project.find(@ecookbook.id) }

Also available in: Unified diff