##// END OF EJS Templates
Adds REST API for versions (#7403)....
Jean-Philippe Lang -
r6060:b86a748b1d3a
parent child
Show More
@@ -0,0 +1,18
1 api.array :versions, api_meta(:total_count => @versions.size) do
2 @versions.each do |version|
3 api.version do
4 api.id version.id
5 api.project(:id => version.project_id, :name => version.project.name) unless version.project.nil?
6
7 api.name version.name
8 api.description version.description
9 api.status version.status
10 api.due_date version.effective_date
11
12 render_api_custom_values version.custom_field_values, api
13
14 api.created_on version.created_on
15 api.updated_on version.updated_on
16 end
17 end
18 end
@@ -0,0 +1,14
1 api.version do
2 api.id @version.id
3 api.project(:id => @version.project_id, :name => @version.project.name) unless @version.project.nil?
4
5 api.name @version.name
6 api.description @version.description
7 api.status @version.status
8 api.due_date @version.effective_date
9
10 render_api_custom_values @version.custom_field_values, api
11
12 api.created_on @version.created_on
13 api.updated_on @version.updated_on
14 end
@@ -0,0 +1,120
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 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.expand_path('../../../test_helper', __FILE__)
19
20 class ApiTest::VersionsTest < ActionController::IntegrationTest
21 fixtures :all
22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 context "/projects/:project_id/versions" do
28 context "GET" do
29 should "return project versions" do
30 get '/projects/1/versions.xml'
31
32 assert_response :success
33 assert_equal 'application/xml', @response.content_type
34 assert_tag :tag => 'versions',
35 :attributes => {:type => 'array'},
36 :child => {
37 :tag => 'version',
38 :child => {
39 :tag => 'id',
40 :content => '2',
41 :sibling => {
42 :tag => 'name',
43 :content => '1.0'
44 }
45 }
46 }
47 end
48 end
49
50 context "POST" do
51 should "create the version" do
52 assert_difference 'Version.count' do
53 post '/projects/1/versions.xml', {:version => {:name => 'API test'}}, :authorization => credentials('jsmith')
54 end
55
56 version = Version.first(:order => 'id DESC')
57 assert_equal 'API test', version.name
58
59 assert_response :created
60 assert_equal 'application/xml', @response.content_type
61 assert_tag 'version', :child => {:tag => 'id', :content => version.id.to_s}
62 end
63
64 context "with failure" do
65 should "return the errors" do
66 assert_no_difference('Version.count') do
67 post '/projects/1/versions.xml', {:version => {:name => ''}}, :authorization => credentials('jsmith')
68 end
69
70 assert_response :unprocessable_entity
71 assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
72 end
73 end
74 end
75 end
76
77 context "/projects/:project_id/versions/:id" do
78 context "GET" do
79 should "return the version" do
80 get '/projects/1/versions/2.xml'
81
82 assert_response :success
83 assert_equal 'application/xml', @response.content_type
84 assert_tag 'version',
85 :child => {
86 :tag => 'id',
87 :content => '2',
88 :sibling => {
89 :tag => 'name',
90 :content => '1.0'
91 }
92 }
93 end
94 end
95
96 context "PUT" do
97 should "update the version" do
98 put '/projects/1/versions/2.xml', {:version => {:name => 'API update'}}, :authorization => credentials('jsmith')
99
100 assert_response :ok
101 assert_equal 'API update', Version.find(2).name
102 end
103 end
104
105 context "DELETE" do
106 should "destroy the version" do
107 assert_difference 'Version.count', -1 do
108 delete '/projects/1/versions/3.xml', {}, :authorization => credentials('jsmith')
109 end
110
111 assert_response :ok
112 assert_nil Version.find_by_id(3)
113 end
114 end
115 end
116
117 def credentials(user, password=nil)
118 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
119 end
120 end
@@ -1,159 +1,192
1 # redMine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class VersionsController < ApplicationController
18 class VersionsController < ApplicationController
19 menu_item :roadmap
19 menu_item :roadmap
20 model_object Version
20 model_object Version
21 before_filter :find_model_object, :except => [:index, :new, :create, :close_completed]
21 before_filter :find_model_object, :except => [:index, :new, :create, :close_completed]
22 before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed]
22 before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed]
23 before_filter :find_project, :only => [:index, :new, :create, :close_completed]
23 before_filter :find_project, :only => [:index, :new, :create, :close_completed]
24 before_filter :authorize
24 before_filter :authorize
25
25
26 accept_key_auth :index, :create, :update, :destroy
27
26 helper :custom_fields
28 helper :custom_fields
27 helper :projects
29 helper :projects
28
30
29 def index
31 def index
30 @trackers = @project.trackers.find(:all, :order => 'position')
32 respond_to do |format|
31 retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
33 format.html {
32 @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
34 @trackers = @project.trackers.find(:all, :order => 'position')
33 project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id]
35 retrieve_selected_tracker_ids(@trackers, @trackers.select {|t| t.is_in_roadmap?})
34
36 @with_subprojects = params[:with_subprojects].nil? ? Setting.display_subprojects_issues? : (params[:with_subprojects] == '1')
35 @versions = @project.shared_versions || []
37 project_ids = @with_subprojects ? @project.self_and_descendants.collect(&:id) : [@project.id]
36 @versions += @project.rolled_up_versions.visible if @with_subprojects
38
37 @versions = @versions.uniq.sort
39 @versions = @project.shared_versions || []
38 @versions.reject! {|version| version.closed? || version.completed? } unless params[:completed]
40 @versions += @project.rolled_up_versions.visible if @with_subprojects
39
41 @versions = @versions.uniq.sort
40 @issues_by_version = {}
42 @versions.reject! {|version| version.closed? || version.completed? } unless params[:completed]
41 unless @selected_tracker_ids.empty?
43
42 @versions.each do |version|
44 @issues_by_version = {}
43 issues = version.fixed_issues.visible.find(:all,
45 unless @selected_tracker_ids.empty?
44 :include => [:project, :status, :tracker, :priority],
46 @versions.each do |version|
45 :conditions => {:tracker_id => @selected_tracker_ids, :project_id => project_ids},
47 issues = version.fixed_issues.visible.find(:all,
46 :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id")
48 :include => [:project, :status, :tracker, :priority],
47 @issues_by_version[version] = issues
49 :conditions => {:tracker_id => @selected_tracker_ids, :project_id => project_ids},
48 end
50 :order => "#{Project.table_name}.lft, #{Tracker.table_name}.position, #{Issue.table_name}.id")
51 @issues_by_version[version] = issues
52 end
53 end
54 @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?}
55 }
56 format.api {
57 @versions = @project.shared_versions.all
58 }
49 end
59 end
50 @versions.reject! {|version| !project_ids.include?(version.project_id) && @issues_by_version[version].blank?}
51 end
60 end
52
61
53 def show
62 def show
54 @issues = @version.fixed_issues.visible.find(:all,
63 respond_to do |format|
55 :include => [:status, :tracker, :priority],
64 format.html {
56 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id")
65 @issues = @version.fixed_issues.visible.find(:all,
66 :include => [:status, :tracker, :priority],
67 :order => "#{Tracker.table_name}.position, #{Issue.table_name}.id")
68 }
69 format.api
70 end
57 end
71 end
58
72
59 def new
73 def new
60 @version = @project.versions.build
74 @version = @project.versions.build
61 if params[:version]
75 if params[:version]
62 attributes = params[:version].dup
76 attributes = params[:version].dup
63 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
77 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
64 @version.attributes = attributes
78 @version.attributes = attributes
65 end
79 end
66 end
80 end
67
81
68 def create
82 def create
69 # TODO: refactor with code above in #new
83 # TODO: refactor with code above in #new
70 @version = @project.versions.build
84 @version = @project.versions.build
71 if params[:version]
85 if params[:version]
72 attributes = params[:version].dup
86 attributes = params[:version].dup
73 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
87 attributes.delete('sharing') unless attributes.nil? || @version.allowed_sharings.include?(attributes['sharing'])
74 @version.attributes = attributes
88 @version.attributes = attributes
75 end
89 end
76
90
77 if request.post?
91 if request.post?
78 if @version.save
92 if @version.save
79 respond_to do |format|
93 respond_to do |format|
80 format.html do
94 format.html do
81 flash[:notice] = l(:notice_successful_create)
95 flash[:notice] = l(:notice_successful_create)
82 redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
96 redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
83 end
97 end
84 format.js do
98 format.js do
85 # IE doesn't support the replace_html rjs method for select box options
99 # IE doesn't support the replace_html rjs method for select box options
86 render(:update) {|page| page.replace "issue_fixed_version_id",
100 render(:update) {|page| page.replace "issue_fixed_version_id",
87 content_tag('select', '<option></option>' + version_options_for_select(@project.shared_versions.open, @version), :id => 'issue_fixed_version_id', :name => 'issue[fixed_version_id]')
101 content_tag('select', '<option></option>' + version_options_for_select(@project.shared_versions.open, @version), :id => 'issue_fixed_version_id', :name => 'issue[fixed_version_id]')
88 }
102 }
89 end
103 end
104 format.api do
105 render :action => 'show', :status => :created, :location => project_version_url(@project, @version)
106 end
90 end
107 end
91 else
108 else
92 respond_to do |format|
109 respond_to do |format|
93 format.html { render :action => 'new' }
110 format.html { render :action => 'new' }
94 format.js do
111 format.js do
95 render(:update) {|page| page.alert(@version.errors.full_messages.join('\n')) }
112 render(:update) {|page| page.alert(@version.errors.full_messages.join('\n')) }
96 end
113 end
114 format.api { render_validation_errors(@version) }
97 end
115 end
98 end
116 end
99 end
117 end
100 end
118 end
101
119
102 def edit
120 def edit
103 end
121 end
104
122
105 def update
123 def update
106 if request.put? && params[:version]
124 if request.put? && params[:version]
107 attributes = params[:version].dup
125 attributes = params[:version].dup
108 attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
126 attributes.delete('sharing') unless @version.allowed_sharings.include?(attributes['sharing'])
109 if @version.update_attributes(attributes)
127 if @version.update_attributes(attributes)
110 flash[:notice] = l(:notice_successful_update)
128 respond_to do |format|
111 redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
129 format.html {
130 flash[:notice] = l(:notice_successful_update)
131 redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
132 }
133 format.api { head :ok }
134 end
112 else
135 else
113 respond_to do |format|
136 respond_to do |format|
114 format.html { render :action => 'edit' }
137 format.html { render :action => 'edit' }
138 format.api { render_validation_errors(@version) }
115 end
139 end
116 end
140 end
117 end
141 end
118 end
142 end
119
143
120 def close_completed
144 def close_completed
121 if request.put?
145 if request.put?
122 @project.close_completed_versions
146 @project.close_completed_versions
123 end
147 end
124 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
148 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
125 end
149 end
126
150
151 verify :method => :delete, :only => :destroy, :render => {:nothing => true, :status => :method_not_allowed }
127 def destroy
152 def destroy
128 if @version.fixed_issues.empty?
153 if @version.fixed_issues.empty?
129 @version.destroy
154 @version.destroy
130 redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
155 respond_to do |format|
156 format.html { redirect_back_or_default :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project }
157 format.api { head :ok }
158 end
131 else
159 else
132 flash[:error] = l(:notice_unable_delete_version)
160 respond_to do |format|
133 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
161 format.html {
162 flash[:error] = l(:notice_unable_delete_version)
163 redirect_to :controller => 'projects', :action => 'settings', :tab => 'versions', :id => @project
164 }
165 format.api { head :unprocessable_entity }
166 end
134 end
167 end
135 end
168 end
136
169
137 def status_by
170 def status_by
138 respond_to do |format|
171 respond_to do |format|
139 format.html { render :action => 'show' }
172 format.html { render :action => 'show' }
140 format.js { render(:update) {|page| page.replace_html 'status_by', render_issue_status_by(@version, params[:status_by])} }
173 format.js { render(:update) {|page| page.replace_html 'status_by', render_issue_status_by(@version, params[:status_by])} }
141 end
174 end
142 end
175 end
143
176
144 private
177 private
145 def find_project
178 def find_project
146 @project = Project.find(params[:project_id])
179 @project = Project.find(params[:project_id])
147 rescue ActiveRecord::RecordNotFound
180 rescue ActiveRecord::RecordNotFound
148 render_404
181 render_404
149 end
182 end
150
183
151 def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil)
184 def retrieve_selected_tracker_ids(selectable_trackers, default_trackers=nil)
152 if ids = params[:tracker_ids]
185 if ids = params[:tracker_ids]
153 @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
186 @selected_tracker_ids = (ids.is_a? Array) ? ids.collect { |id| id.to_i.to_s } : ids.split('/').collect { |id| id.to_i.to_s }
154 else
187 else
155 @selected_tracker_ids = (default_trackers || selectable_trackers).collect {|t| t.id.to_s }
188 @selected_tracker_ids = (default_trackers || selectable_trackers).collect {|t| t.id.to_s }
156 end
189 end
157 end
190 end
158
191
159 end
192 end
@@ -1,41 +1,41
1 <% if @project.shared_versions.any? %>
1 <% if @project.shared_versions.any? %>
2 <table class="list versions">
2 <table class="list versions">
3 <thead><tr>
3 <thead><tr>
4 <th><%= l(:label_version) %></th>
4 <th><%= l(:label_version) %></th>
5 <th><%= l(:field_effective_date) %></th>
5 <th><%= l(:field_effective_date) %></th>
6 <th><%= l(:field_description) %></th>
6 <th><%= l(:field_description) %></th>
7 <th><%= l(:field_status) %></th>
7 <th><%= l(:field_status) %></th>
8 <th><%= l(:field_sharing) %></th>
8 <th><%= l(:field_sharing) %></th>
9 <th><%= l(:label_wiki_page) %></th>
9 <th><%= l(:label_wiki_page) %></th>
10 <th style="width:15%"></th>
10 <th style="width:15%"></th>
11 </tr></thead>
11 </tr></thead>
12 <tbody>
12 <tbody>
13 <% for version in @project.shared_versions.sort %>
13 <% for version in @project.shared_versions.sort %>
14 <tr class="version <%= cycle 'odd', 'even' %> <%=h version.status %> <%= 'shared' if version.project != @project %>">
14 <tr class="version <%= cycle 'odd', 'even' %> <%=h version.status %> <%= 'shared' if version.project != @project %>">
15 <td class="name"><%= link_to_version version %></td>
15 <td class="name"><%= link_to_version version %></td>
16 <td class="date"><%= format_date(version.effective_date) %></td>
16 <td class="date"><%= format_date(version.effective_date) %></td>
17 <td class="description"><%=h version.description %></td>
17 <td class="description"><%=h version.description %></td>
18 <td class="status"><%= l("version_status_#{version.status}") %></td>
18 <td class="status"><%= l("version_status_#{version.status}") %></td>
19 <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
19 <td class="sharing"><%=h format_version_sharing(version.sharing) %></td>
20 <td><%= link_to_if_authorized(h(version.wiki_page_title), {:controller => 'wiki', :action => 'show', :project_id => version.project, :id => Wiki.titleize(version.wiki_page_title)}) || h(version.wiki_page_title) unless version.wiki_page_title.blank? || version.project.wiki.nil? %></td>
20 <td><%= link_to_if_authorized(h(version.wiki_page_title), {:controller => 'wiki', :action => 'show', :project_id => version.project, :id => Wiki.titleize(version.wiki_page_title)}) || h(version.wiki_page_title) unless version.wiki_page_title.blank? || version.project.wiki.nil? %></td>
21 <td class="buttons">
21 <td class="buttons">
22 <% if version.project == @project %>
22 <% if version.project == @project && User.current.allowed_to?(:manage_versions, @project) %>
23 <%= link_to_if_authorized l(:button_edit), {:controller => 'versions', :action => 'edit', :id => version }, :class => 'icon icon-edit' %>
23 <%= link_to l(:button_edit), edit_project_version_path(@project, version), :class => 'icon icon-edit' %>
24 <%= link_to_if_authorized l(:button_delete), {:controller => 'versions', :action => 'destroy', :id => version}, :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
24 <%= link_to l(:button_delete), project_version_path(@project, version), :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
25 <% end %>
25 <% end %>
26 </td>
26 </td>
27 </tr>
27 </tr>
28 <% end; reset_cycle %>
28 <% end; reset_cycle %>
29 </tbody>
29 </tbody>
30 </table>
30 </table>
31 <% else %>
31 <% else %>
32 <p class="nodata"><%= l(:label_no_data) %></p>
32 <p class="nodata"><%= l(:label_no_data) %></p>
33 <% end %>
33 <% end %>
34
34
35 <div class="contextual">
35 <div class="contextual">
36 <% if @project.versions.any? %>
36 <% if @project.versions.any? %>
37 <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %>
37 <%= link_to l(:label_close_versions), close_completed_project_versions_path(@project), :method => :put %>
38 <% end %>
38 <% end %>
39 </div>
39 </div>
40
40
41 <p><%= link_to_if_authorized l(:label_version_new), :controller => 'versions', :action => 'new', :project_id => @project %></p>
41 <p><%= link_to_if_authorized l(:label_version_new), :controller => 'versions', :action => 'new', :project_id => @project %></p>
@@ -1,56 +1,56
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to_if_authorized l(:button_edit), {:controller => 'versions', :action => 'edit', :id => @version}, :class => 'icon icon-edit' %>
2 <%= link_to(l(:button_edit), edit_project_version_path(@version.project, @version), :class => 'icon icon-edit') if User.current.allowed_to?(:manage_versions, @version.project) %>
3 <%= link_to_if_authorized(l(:button_edit_associated_wikipage, :page_title => @version.wiki_page_title), {:controller => 'wiki', :action => 'edit', :project_id => @version.project, :id => Wiki.titleize(@version.wiki_page_title)}, :class => 'icon icon-edit') unless @version.wiki_page_title.blank? || @version.project.wiki.nil? %>
3 <%= link_to_if_authorized(l(:button_edit_associated_wikipage, :page_title => @version.wiki_page_title), {:controller => 'wiki', :action => 'edit', :project_id => @version.project, :id => Wiki.titleize(@version.wiki_page_title)}, :class => 'icon icon-edit') unless @version.wiki_page_title.blank? || @version.project.wiki.nil? %>
4 <%= link_to_if_authorized l(:button_delete), {:controller => 'versions', :action => 'destroy', :id => @version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)},
4 <%= link_to(l(:button_delete), project_version_path(@version.project, @version, :back_url => url_for(:controller => 'versions', :action => 'index', :project_id => @version.project)),
5 :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del' %>
5 :confirm => l(:text_are_you_sure), :method => :delete, :class => 'icon icon-del') if User.current.allowed_to?(:manage_versions, @version.project) %>
6 <%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
6 <%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
7 </div>
7 </div>
8
8
9 <h2><%= h(@version.name) %></h2>
9 <h2><%= h(@version.name) %></h2>
10
10
11 <div id="roadmap">
11 <div id="roadmap">
12 <%= render :partial => 'versions/overview', :locals => {:version => @version} %>
12 <%= render :partial => 'versions/overview', :locals => {:version => @version} %>
13 <%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
13 <%= render(:partial => "wiki/content", :locals => {:content => @version.wiki_page.content}) if @version.wiki_page %>
14
14
15 <div id="version-summary">
15 <div id="version-summary">
16 <% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
16 <% if @version.estimated_hours > 0 || User.current.allowed_to?(:view_time_entries, @project) %>
17 <fieldset><legend><%= l(:label_time_tracking) %></legend>
17 <fieldset><legend><%= l(:label_time_tracking) %></legend>
18 <table>
18 <table>
19 <tr>
19 <tr>
20 <td width="130px" align="right"><%= l(:field_estimated_hours) %></td>
20 <td width="130px" align="right"><%= l(:field_estimated_hours) %></td>
21 <td width="240px" class="total-hours"width="130px" align="right"><%= html_hours(l_hours(@version.estimated_hours)) %></td>
21 <td width="240px" class="total-hours"width="130px" align="right"><%= html_hours(l_hours(@version.estimated_hours)) %></td>
22 </tr>
22 </tr>
23 <% if User.current.allowed_to?(:view_time_entries, @project) %>
23 <% if User.current.allowed_to?(:view_time_entries, @project) %>
24 <tr>
24 <tr>
25 <td width="130px" align="right"><%= l(:label_spent_time) %></td>
25 <td width="130px" align="right"><%= l(:label_spent_time) %></td>
26 <td width="240px" class="total-hours"><%= html_hours(l_hours(@version.spent_hours)) %></td>
26 <td width="240px" class="total-hours"><%= html_hours(l_hours(@version.spent_hours)) %></td>
27 </tr>
27 </tr>
28 <% end %>
28 <% end %>
29 </table>
29 </table>
30 </fieldset>
30 </fieldset>
31 <% end %>
31 <% end %>
32
32
33 <div id="status_by">
33 <div id="status_by">
34 <%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
34 <%= render_issue_status_by(@version, params[:status_by]) if @version.fixed_issues.count > 0 %>
35 </div>
35 </div>
36 </div>
36 </div>
37
37
38 <% if @issues.present? %>
38 <% if @issues.present? %>
39 <% form_tag({}) do -%>
39 <% form_tag({}) do -%>
40 <table class="list related-issues">
40 <table class="list related-issues">
41 <caption><%= l(:label_related_issues) %></caption>
41 <caption><%= l(:label_related_issues) %></caption>
42 <%- @issues.each do |issue| -%>
42 <%- @issues.each do |issue| -%>
43 <tr class="hascontextmenu">
43 <tr class="hascontextmenu">
44 <td class="checkbox"><%= check_box_tag 'ids[]', issue.id %></td>
44 <td class="checkbox"><%= check_box_tag 'ids[]', issue.id %></td>
45 <td><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
45 <td><%= link_to_issue(issue, :project => (@project != issue.project)) %></td>
46 </tr>
46 </tr>
47 <% end %>
47 <% end %>
48 </table>
48 </table>
49 <% end %>
49 <% end %>
50 <%= context_menu issues_context_menu_path %>
50 <%= context_menu issues_context_menu_path %>
51 <% end %>
51 <% end %>
52 </div>
52 </div>
53
53
54 <%= call_hook :view_versions_show_bottom, :version => @version %>
54 <%= call_hook :view_versions_show_bottom, :version => @version %>
55
55
56 <% html_title @version.name %>
56 <% html_title @version.name %>
@@ -1,375 +1,392
1 # redMine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class RoutingTest < ActionController::IntegrationTest
20 class RoutingTest < ActionController::IntegrationTest
21 context "activities" do
21 context "activities" do
22 should_route :get, "/activity", :controller => 'activities', :action => 'index', :id => nil
22 should_route :get, "/activity", :controller => 'activities', :action => 'index', :id => nil
23 should_route :get, "/activity.atom", :controller => 'activities', :action => 'index', :id => nil, :format => 'atom'
23 should_route :get, "/activity.atom", :controller => 'activities', :action => 'index', :id => nil, :format => 'atom'
24 end
24 end
25
25
26 context "attachments" do
26 context "attachments" do
27 should_route :get, "/attachments/1", :controller => 'attachments', :action => 'show', :id => '1'
27 should_route :get, "/attachments/1", :controller => 'attachments', :action => 'show', :id => '1'
28 should_route :get, "/attachments/1/filename.ext", :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'
28 should_route :get, "/attachments/1/filename.ext", :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'
29 should_route :get, "/attachments/download/1", :controller => 'attachments', :action => 'download', :id => '1'
29 should_route :get, "/attachments/download/1", :controller => 'attachments', :action => 'download', :id => '1'
30 should_route :get, "/attachments/download/1/filename.ext", :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'
30 should_route :get, "/attachments/download/1/filename.ext", :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'
31 end
31 end
32
32
33 context "boards" do
33 context "boards" do
34 should_route :get, "/projects/world_domination/boards", :controller => 'boards', :action => 'index', :project_id => 'world_domination'
34 should_route :get, "/projects/world_domination/boards", :controller => 'boards', :action => 'index', :project_id => 'world_domination'
35 should_route :get, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
35 should_route :get, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
36 should_route :get, "/projects/world_domination/boards/44", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44'
36 should_route :get, "/projects/world_domination/boards/44", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44'
37 should_route :get, "/projects/world_domination/boards/44.atom", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44', :format => 'atom'
37 should_route :get, "/projects/world_domination/boards/44.atom", :controller => 'boards', :action => 'show', :project_id => 'world_domination', :id => '44', :format => 'atom'
38 should_route :get, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
38 should_route :get, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
39
39
40 should_route :post, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
40 should_route :post, "/projects/world_domination/boards/new", :controller => 'boards', :action => 'new', :project_id => 'world_domination'
41 should_route :post, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
41 should_route :post, "/projects/world_domination/boards/44/edit", :controller => 'boards', :action => 'edit', :project_id => 'world_domination', :id => '44'
42 should_route :post, "/projects/world_domination/boards/44/destroy", :controller => 'boards', :action => 'destroy', :project_id => 'world_domination', :id => '44'
42 should_route :post, "/projects/world_domination/boards/44/destroy", :controller => 'boards', :action => 'destroy', :project_id => 'world_domination', :id => '44'
43
43
44 end
44 end
45
45
46 context "documents" do
46 context "documents" do
47 should_route :get, "/projects/567/documents", :controller => 'documents', :action => 'index', :project_id => '567'
47 should_route :get, "/projects/567/documents", :controller => 'documents', :action => 'index', :project_id => '567'
48 should_route :get, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
48 should_route :get, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
49 should_route :get, "/documents/22", :controller => 'documents', :action => 'show', :id => '22'
49 should_route :get, "/documents/22", :controller => 'documents', :action => 'show', :id => '22'
50 should_route :get, "/documents/22/edit", :controller => 'documents', :action => 'edit', :id => '22'
50 should_route :get, "/documents/22/edit", :controller => 'documents', :action => 'edit', :id => '22'
51
51
52 should_route :post, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
52 should_route :post, "/projects/567/documents/new", :controller => 'documents', :action => 'new', :project_id => '567'
53 should_route :post, "/documents/567/edit", :controller => 'documents', :action => 'edit', :id => '567'
53 should_route :post, "/documents/567/edit", :controller => 'documents', :action => 'edit', :id => '567'
54 should_route :post, "/documents/567/destroy", :controller => 'documents', :action => 'destroy', :id => '567'
54 should_route :post, "/documents/567/destroy", :controller => 'documents', :action => 'destroy', :id => '567'
55 end
55 end
56
56
57 context "issues" do
57 context "issues" do
58 # REST actions
58 # REST actions
59 should_route :get, "/issues", :controller => 'issues', :action => 'index'
59 should_route :get, "/issues", :controller => 'issues', :action => 'index'
60 should_route :get, "/issues.pdf", :controller => 'issues', :action => 'index', :format => 'pdf'
60 should_route :get, "/issues.pdf", :controller => 'issues', :action => 'index', :format => 'pdf'
61 should_route :get, "/issues.atom", :controller => 'issues', :action => 'index', :format => 'atom'
61 should_route :get, "/issues.atom", :controller => 'issues', :action => 'index', :format => 'atom'
62 should_route :get, "/issues.xml", :controller => 'issues', :action => 'index', :format => 'xml'
62 should_route :get, "/issues.xml", :controller => 'issues', :action => 'index', :format => 'xml'
63 should_route :get, "/projects/23/issues", :controller => 'issues', :action => 'index', :project_id => '23'
63 should_route :get, "/projects/23/issues", :controller => 'issues', :action => 'index', :project_id => '23'
64 should_route :get, "/projects/23/issues.pdf", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
64 should_route :get, "/projects/23/issues.pdf", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
65 should_route :get, "/projects/23/issues.atom", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
65 should_route :get, "/projects/23/issues.atom", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
66 should_route :get, "/projects/23/issues.xml", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'xml'
66 should_route :get, "/projects/23/issues.xml", :controller => 'issues', :action => 'index', :project_id => '23', :format => 'xml'
67 should_route :get, "/issues/64", :controller => 'issues', :action => 'show', :id => '64'
67 should_route :get, "/issues/64", :controller => 'issues', :action => 'show', :id => '64'
68 should_route :get, "/issues/64.pdf", :controller => 'issues', :action => 'show', :id => '64', :format => 'pdf'
68 should_route :get, "/issues/64.pdf", :controller => 'issues', :action => 'show', :id => '64', :format => 'pdf'
69 should_route :get, "/issues/64.atom", :controller => 'issues', :action => 'show', :id => '64', :format => 'atom'
69 should_route :get, "/issues/64.atom", :controller => 'issues', :action => 'show', :id => '64', :format => 'atom'
70 should_route :get, "/issues/64.xml", :controller => 'issues', :action => 'show', :id => '64', :format => 'xml'
70 should_route :get, "/issues/64.xml", :controller => 'issues', :action => 'show', :id => '64', :format => 'xml'
71
71
72 should_route :get, "/projects/23/issues/new", :controller => 'issues', :action => 'new', :project_id => '23'
72 should_route :get, "/projects/23/issues/new", :controller => 'issues', :action => 'new', :project_id => '23'
73 should_route :post, "/projects/23/issues", :controller => 'issues', :action => 'create', :project_id => '23'
73 should_route :post, "/projects/23/issues", :controller => 'issues', :action => 'create', :project_id => '23'
74 should_route :post, "/issues.xml", :controller => 'issues', :action => 'create', :format => 'xml'
74 should_route :post, "/issues.xml", :controller => 'issues', :action => 'create', :format => 'xml'
75
75
76 should_route :get, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
76 should_route :get, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
77 # TODO: Should use PUT
77 # TODO: Should use PUT
78 should_route :post, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
78 should_route :post, "/issues/64/edit", :controller => 'issues', :action => 'edit', :id => '64'
79 should_route :put, "/issues/1.xml", :controller => 'issues', :action => 'update', :id => '1', :format => 'xml'
79 should_route :put, "/issues/1.xml", :controller => 'issues', :action => 'update', :id => '1', :format => 'xml'
80
80
81 # TODO: Should use DELETE
81 # TODO: Should use DELETE
82 should_route :post, "/issues/64/destroy", :controller => 'issues', :action => 'destroy', :id => '64'
82 should_route :post, "/issues/64/destroy", :controller => 'issues', :action => 'destroy', :id => '64'
83 should_route :delete, "/issues/1.xml", :controller => 'issues', :action => 'destroy', :id => '1', :format => 'xml'
83 should_route :delete, "/issues/1.xml", :controller => 'issues', :action => 'destroy', :id => '1', :format => 'xml'
84
84
85 # Extra actions
85 # Extra actions
86 should_route :get, "/projects/23/issues/64/copy", :controller => 'issues', :action => 'new', :project_id => '23', :copy_from => '64'
86 should_route :get, "/projects/23/issues/64/copy", :controller => 'issues', :action => 'new', :project_id => '23', :copy_from => '64'
87
87
88 should_route :get, "/issues/move/new", :controller => 'issue_moves', :action => 'new'
88 should_route :get, "/issues/move/new", :controller => 'issue_moves', :action => 'new'
89 should_route :post, "/issues/move", :controller => 'issue_moves', :action => 'create'
89 should_route :post, "/issues/move", :controller => 'issue_moves', :action => 'create'
90
90
91 should_route :post, "/issues/1/quoted", :controller => 'journals', :action => 'new', :id => '1'
91 should_route :post, "/issues/1/quoted", :controller => 'journals', :action => 'new', :id => '1'
92
92
93 should_route :get, "/issues/calendar", :controller => 'calendars', :action => 'show'
93 should_route :get, "/issues/calendar", :controller => 'calendars', :action => 'show'
94 should_route :get, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'show', :project_id => 'project-name'
94 should_route :get, "/projects/project-name/issues/calendar", :controller => 'calendars', :action => 'show', :project_id => 'project-name'
95
95
96 should_route :get, "/issues/gantt", :controller => 'gantts', :action => 'show'
96 should_route :get, "/issues/gantt", :controller => 'gantts', :action => 'show'
97 should_route :get, "/issues/gantt.pdf", :controller => 'gantts', :action => 'show', :format => 'pdf'
97 should_route :get, "/issues/gantt.pdf", :controller => 'gantts', :action => 'show', :format => 'pdf'
98 should_route :get, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'show', :project_id => 'project-name'
98 should_route :get, "/projects/project-name/issues/gantt", :controller => 'gantts', :action => 'show', :project_id => 'project-name'
99 should_route :get, "/projects/project-name/issues/gantt.pdf", :controller => 'gantts', :action => 'show', :project_id => 'project-name', :format => 'pdf'
99 should_route :get, "/projects/project-name/issues/gantt.pdf", :controller => 'gantts', :action => 'show', :project_id => 'project-name', :format => 'pdf'
100
100
101 should_route :get, "/issues/auto_complete", :controller => 'auto_completes', :action => 'issues'
101 should_route :get, "/issues/auto_complete", :controller => 'auto_completes', :action => 'issues'
102
102
103 should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
103 should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
104 should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
104 should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
105 should_route :get, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
105 should_route :get, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
106 should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
106 should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
107
107
108 should_route :get, "/issues/changes", :controller => 'journals', :action => 'index'
108 should_route :get, "/issues/changes", :controller => 'journals', :action => 'index'
109
109
110 should_route :get, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_edit'
110 should_route :get, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_edit'
111 should_route :post, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_update'
111 should_route :post, "/issues/bulk_edit", :controller => 'issues', :action => 'bulk_update'
112 end
112 end
113
113
114 context "issue categories" do
114 context "issue categories" do
115 should_route :get, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
115 should_route :get, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
116
116
117 should_route :post, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
117 should_route :post, "/projects/test/issue_categories/new", :controller => 'issue_categories', :action => 'new', :project_id => 'test'
118 end
118 end
119
119
120 context "issue relations" do
120 context "issue relations" do
121 should_route :get, "/issues/1/relations", :controller => 'issue_relations', :action => 'index', :issue_id => '1'
121 should_route :get, "/issues/1/relations", :controller => 'issue_relations', :action => 'index', :issue_id => '1'
122 should_route :get, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'index', :issue_id => '1', :format => 'xml'
122 should_route :get, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'index', :issue_id => '1', :format => 'xml'
123 should_route :get, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'index', :issue_id => '1', :format => 'json'
123 should_route :get, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'index', :issue_id => '1', :format => 'json'
124
124
125 should_route :post, "/issues/1/relations", :controller => 'issue_relations', :action => 'create', :issue_id => '1'
125 should_route :post, "/issues/1/relations", :controller => 'issue_relations', :action => 'create', :issue_id => '1'
126 should_route :post, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'xml'
126 should_route :post, "/issues/1/relations.xml", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'xml'
127 should_route :post, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'json'
127 should_route :post, "/issues/1/relations.json", :controller => 'issue_relations', :action => 'create', :issue_id => '1', :format => 'json'
128
128
129 should_route :get, "/issues/1/relations/23", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23'
129 should_route :get, "/issues/1/relations/23", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23'
130 should_route :get, "/issues/1/relations/23.xml", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23', :format => 'xml'
130 should_route :get, "/issues/1/relations/23.xml", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23', :format => 'xml'
131 should_route :get, "/issues/1/relations/23.json", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23', :format => 'json'
131 should_route :get, "/issues/1/relations/23.json", :controller => 'issue_relations', :action => 'show', :issue_id => '1', :id => '23', :format => 'json'
132
132
133 should_route :delete, "/issues/1/relations/23", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23'
133 should_route :delete, "/issues/1/relations/23", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23'
134 should_route :delete, "/issues/1/relations/23.xml", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23', :format => 'xml'
134 should_route :delete, "/issues/1/relations/23.xml", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23', :format => 'xml'
135 should_route :delete, "/issues/1/relations/23.json", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23', :format => 'json'
135 should_route :delete, "/issues/1/relations/23.json", :controller => 'issue_relations', :action => 'destroy', :issue_id => '1', :id => '23', :format => 'json'
136 end
136 end
137
137
138 context "issue reports" do
138 context "issue reports" do
139 should_route :get, "/projects/567/issues/report", :controller => 'reports', :action => 'issue_report', :id => '567'
139 should_route :get, "/projects/567/issues/report", :controller => 'reports', :action => 'issue_report', :id => '567'
140 should_route :get, "/projects/567/issues/report/assigned_to", :controller => 'reports', :action => 'issue_report_details', :id => '567', :detail => 'assigned_to'
140 should_route :get, "/projects/567/issues/report/assigned_to", :controller => 'reports', :action => 'issue_report_details', :id => '567', :detail => 'assigned_to'
141 end
141 end
142
142
143 context "members" do
143 context "members" do
144 should_route :post, "/projects/5234/members/new", :controller => 'members', :action => 'new', :id => '5234'
144 should_route :post, "/projects/5234/members/new", :controller => 'members', :action => 'new', :id => '5234'
145 end
145 end
146
146
147 context "messages" do
147 context "messages" do
148 should_route :get, "/boards/22/topics/2", :controller => 'messages', :action => 'show', :id => '2', :board_id => '22'
148 should_route :get, "/boards/22/topics/2", :controller => 'messages', :action => 'show', :id => '2', :board_id => '22'
149 should_route :get, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
149 should_route :get, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
150 should_route :get, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
150 should_route :get, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
151
151
152 should_route :post, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
152 should_route :post, "/boards/lala/topics/new", :controller => 'messages', :action => 'new', :board_id => 'lala'
153 should_route :post, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
153 should_route :post, "/boards/lala/topics/22/edit", :controller => 'messages', :action => 'edit', :id => '22', :board_id => 'lala'
154 should_route :post, "/boards/22/topics/555/replies", :controller => 'messages', :action => 'reply', :id => '555', :board_id => '22'
154 should_route :post, "/boards/22/topics/555/replies", :controller => 'messages', :action => 'reply', :id => '555', :board_id => '22'
155 should_route :post, "/boards/22/topics/555/destroy", :controller => 'messages', :action => 'destroy', :id => '555', :board_id => '22'
155 should_route :post, "/boards/22/topics/555/destroy", :controller => 'messages', :action => 'destroy', :id => '555', :board_id => '22'
156 end
156 end
157
157
158 context "news" do
158 context "news" do
159 should_route :get, "/news", :controller => 'news', :action => 'index'
159 should_route :get, "/news", :controller => 'news', :action => 'index'
160 should_route :get, "/news.atom", :controller => 'news', :action => 'index', :format => 'atom'
160 should_route :get, "/news.atom", :controller => 'news', :action => 'index', :format => 'atom'
161 should_route :get, "/news.xml", :controller => 'news', :action => 'index', :format => 'xml'
161 should_route :get, "/news.xml", :controller => 'news', :action => 'index', :format => 'xml'
162 should_route :get, "/news.json", :controller => 'news', :action => 'index', :format => 'json'
162 should_route :get, "/news.json", :controller => 'news', :action => 'index', :format => 'json'
163 should_route :get, "/projects/567/news", :controller => 'news', :action => 'index', :project_id => '567'
163 should_route :get, "/projects/567/news", :controller => 'news', :action => 'index', :project_id => '567'
164 should_route :get, "/projects/567/news.atom", :controller => 'news', :action => 'index', :format => 'atom', :project_id => '567'
164 should_route :get, "/projects/567/news.atom", :controller => 'news', :action => 'index', :format => 'atom', :project_id => '567'
165 should_route :get, "/projects/567/news.xml", :controller => 'news', :action => 'index', :format => 'xml', :project_id => '567'
165 should_route :get, "/projects/567/news.xml", :controller => 'news', :action => 'index', :format => 'xml', :project_id => '567'
166 should_route :get, "/projects/567/news.json", :controller => 'news', :action => 'index', :format => 'json', :project_id => '567'
166 should_route :get, "/projects/567/news.json", :controller => 'news', :action => 'index', :format => 'json', :project_id => '567'
167 should_route :get, "/news/2", :controller => 'news', :action => 'show', :id => '2'
167 should_route :get, "/news/2", :controller => 'news', :action => 'show', :id => '2'
168 should_route :get, "/projects/567/news/new", :controller => 'news', :action => 'new', :project_id => '567'
168 should_route :get, "/projects/567/news/new", :controller => 'news', :action => 'new', :project_id => '567'
169 should_route :get, "/news/234", :controller => 'news', :action => 'show', :id => '234'
169 should_route :get, "/news/234", :controller => 'news', :action => 'show', :id => '234'
170 should_route :get, "/news/567/edit", :controller => 'news', :action => 'edit', :id => '567'
170 should_route :get, "/news/567/edit", :controller => 'news', :action => 'edit', :id => '567'
171 should_route :get, "/news/preview", :controller => 'previews', :action => 'news'
171 should_route :get, "/news/preview", :controller => 'previews', :action => 'news'
172
172
173 should_route :post, "/projects/567/news", :controller => 'news', :action => 'create', :project_id => '567'
173 should_route :post, "/projects/567/news", :controller => 'news', :action => 'create', :project_id => '567'
174 should_route :post, "/news/567/comments", :controller => 'comments', :action => 'create', :id => '567'
174 should_route :post, "/news/567/comments", :controller => 'comments', :action => 'create', :id => '567'
175
175
176 should_route :put, "/news/567", :controller => 'news', :action => 'update', :id => '567'
176 should_route :put, "/news/567", :controller => 'news', :action => 'update', :id => '567'
177
177
178 should_route :delete, "/news/567", :controller => 'news', :action => 'destroy', :id => '567'
178 should_route :delete, "/news/567", :controller => 'news', :action => 'destroy', :id => '567'
179 should_route :delete, "/news/567/comments/15", :controller => 'comments', :action => 'destroy', :id => '567', :comment_id => '15'
179 should_route :delete, "/news/567/comments/15", :controller => 'comments', :action => 'destroy', :id => '567', :comment_id => '15'
180 end
180 end
181
181
182 context "projects" do
182 context "projects" do
183 should_route :get, "/projects", :controller => 'projects', :action => 'index'
183 should_route :get, "/projects", :controller => 'projects', :action => 'index'
184 should_route :get, "/projects.atom", :controller => 'projects', :action => 'index', :format => 'atom'
184 should_route :get, "/projects.atom", :controller => 'projects', :action => 'index', :format => 'atom'
185 should_route :get, "/projects.xml", :controller => 'projects', :action => 'index', :format => 'xml'
185 should_route :get, "/projects.xml", :controller => 'projects', :action => 'index', :format => 'xml'
186 should_route :get, "/projects/new", :controller => 'projects', :action => 'new'
186 should_route :get, "/projects/new", :controller => 'projects', :action => 'new'
187 should_route :get, "/projects/test", :controller => 'projects', :action => 'show', :id => 'test'
187 should_route :get, "/projects/test", :controller => 'projects', :action => 'show', :id => 'test'
188 should_route :get, "/projects/1.xml", :controller => 'projects', :action => 'show', :id => '1', :format => 'xml'
188 should_route :get, "/projects/1.xml", :controller => 'projects', :action => 'show', :id => '1', :format => 'xml'
189 should_route :get, "/projects/4223/settings", :controller => 'projects', :action => 'settings', :id => '4223'
189 should_route :get, "/projects/4223/settings", :controller => 'projects', :action => 'settings', :id => '4223'
190 should_route :get, "/projects/4223/settings/members", :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
190 should_route :get, "/projects/4223/settings/members", :controller => 'projects', :action => 'settings', :id => '4223', :tab => 'members'
191 should_route :get, "/projects/33/files", :controller => 'files', :action => 'index', :project_id => '33'
191 should_route :get, "/projects/33/files", :controller => 'files', :action => 'index', :project_id => '33'
192 should_route :get, "/projects/33/files/new", :controller => 'files', :action => 'new', :project_id => '33'
192 should_route :get, "/projects/33/files/new", :controller => 'files', :action => 'new', :project_id => '33'
193 should_route :get, "/projects/33/roadmap", :controller => 'versions', :action => 'index', :project_id => '33'
193 should_route :get, "/projects/33/roadmap", :controller => 'versions', :action => 'index', :project_id => '33'
194 should_route :get, "/projects/33/activity", :controller => 'activities', :action => 'index', :id => '33'
194 should_route :get, "/projects/33/activity", :controller => 'activities', :action => 'index', :id => '33'
195 should_route :get, "/projects/33/activity.atom", :controller => 'activities', :action => 'index', :id => '33', :format => 'atom'
195 should_route :get, "/projects/33/activity.atom", :controller => 'activities', :action => 'index', :id => '33', :format => 'atom'
196
196
197 should_route :post, "/projects", :controller => 'projects', :action => 'create'
197 should_route :post, "/projects", :controller => 'projects', :action => 'create'
198 should_route :post, "/projects.xml", :controller => 'projects', :action => 'create', :format => 'xml'
198 should_route :post, "/projects.xml", :controller => 'projects', :action => 'create', :format => 'xml'
199 should_route :post, "/projects/33/files", :controller => 'files', :action => 'create', :project_id => '33'
199 should_route :post, "/projects/33/files", :controller => 'files', :action => 'create', :project_id => '33'
200 should_route :post, "/projects/64/archive", :controller => 'projects', :action => 'archive', :id => '64'
200 should_route :post, "/projects/64/archive", :controller => 'projects', :action => 'archive', :id => '64'
201 should_route :post, "/projects/64/unarchive", :controller => 'projects', :action => 'unarchive', :id => '64'
201 should_route :post, "/projects/64/unarchive", :controller => 'projects', :action => 'unarchive', :id => '64'
202
202
203 should_route :put, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'update', :project_id => '64'
203 should_route :put, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'update', :project_id => '64'
204 should_route :put, "/projects/4223", :controller => 'projects', :action => 'update', :id => '4223'
204 should_route :put, "/projects/4223", :controller => 'projects', :action => 'update', :id => '4223'
205 should_route :put, "/projects/1.xml", :controller => 'projects', :action => 'update', :id => '1', :format => 'xml'
205 should_route :put, "/projects/1.xml", :controller => 'projects', :action => 'update', :id => '1', :format => 'xml'
206
206
207 should_route :delete, "/projects/64", :controller => 'projects', :action => 'destroy', :id => '64'
207 should_route :delete, "/projects/64", :controller => 'projects', :action => 'destroy', :id => '64'
208 should_route :delete, "/projects/1.xml", :controller => 'projects', :action => 'destroy', :id => '1', :format => 'xml'
208 should_route :delete, "/projects/1.xml", :controller => 'projects', :action => 'destroy', :id => '1', :format => 'xml'
209 should_route :delete, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'destroy', :project_id => '64'
209 should_route :delete, "/projects/64/enumerations", :controller => 'project_enumerations', :action => 'destroy', :project_id => '64'
210 end
210 end
211
211
212 context "queries" do
212 context "queries" do
213 should_route :get, "/queries/new", :controller => 'queries', :action => 'new'
213 should_route :get, "/queries/new", :controller => 'queries', :action => 'new'
214 should_route :get, "/projects/redmine/queries/new", :controller => 'queries', :action => 'new', :project_id => 'redmine'
214 should_route :get, "/projects/redmine/queries/new", :controller => 'queries', :action => 'new', :project_id => 'redmine'
215
215
216 should_route :post, "/queries/new", :controller => 'queries', :action => 'new'
216 should_route :post, "/queries/new", :controller => 'queries', :action => 'new'
217 should_route :post, "/projects/redmine/queries/new", :controller => 'queries', :action => 'new', :project_id => 'redmine'
217 should_route :post, "/projects/redmine/queries/new", :controller => 'queries', :action => 'new', :project_id => 'redmine'
218 end
218 end
219
219
220 context "repositories" do
220 context "repositories" do
221 should_route :get, "/projects/redmine/repository", :controller => 'repositories', :action => 'show', :id => 'redmine'
221 should_route :get, "/projects/redmine/repository", :controller => 'repositories', :action => 'show', :id => 'redmine'
222 should_route :get, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
222 should_route :get, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
223 should_route :get, "/projects/redmine/repository/revisions", :controller => 'repositories', :action => 'revisions', :id => 'redmine'
223 should_route :get, "/projects/redmine/repository/revisions", :controller => 'repositories', :action => 'revisions', :id => 'redmine'
224 should_route :get, "/projects/redmine/repository/revisions.atom", :controller => 'repositories', :action => 'revisions', :id => 'redmine', :format => 'atom'
224 should_route :get, "/projects/redmine/repository/revisions.atom", :controller => 'repositories', :action => 'revisions', :id => 'redmine', :format => 'atom'
225 should_route :get, "/projects/redmine/repository/revisions/2457", :controller => 'repositories', :action => 'revision', :id => 'redmine', :rev => '2457'
225 should_route :get, "/projects/redmine/repository/revisions/2457", :controller => 'repositories', :action => 'revision', :id => 'redmine', :rev => '2457'
226 should_route :get, "/projects/redmine/repository/revisions/2457/diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457'
226 should_route :get, "/projects/redmine/repository/revisions/2457/diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457'
227 should_route :get, "/projects/redmine/repository/revisions/2457/diff.diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457', :format => 'diff'
227 should_route :get, "/projects/redmine/repository/revisions/2457/diff.diff", :controller => 'repositories', :action => 'diff', :id => 'redmine', :rev => '2457', :format => 'diff'
228 should_route :get, "/projects/redmine/repository/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c]
228 should_route :get, "/projects/redmine/repository/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c]
229 should_route :get, "/projects/redmine/repository/revisions/2/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
229 should_route :get, "/projects/redmine/repository/revisions/2/diff/path/to/file.c", :controller => 'repositories', :action => 'diff', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
230 should_route :get, "/projects/redmine/repository/browse/path/to/file.c", :controller => 'repositories', :action => 'browse', :id => 'redmine', :path => %w[path to file.c]
230 should_route :get, "/projects/redmine/repository/browse/path/to/file.c", :controller => 'repositories', :action => 'browse', :id => 'redmine', :path => %w[path to file.c]
231 should_route :get, "/projects/redmine/repository/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c]
231 should_route :get, "/projects/redmine/repository/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c]
232 should_route :get, "/projects/redmine/repository/revisions/2/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
232 should_route :get, "/projects/redmine/repository/revisions/2/entry/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2'
233 should_route :get, "/projects/redmine/repository/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :format => 'raw'
233 should_route :get, "/projects/redmine/repository/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :format => 'raw'
234 should_route :get, "/projects/redmine/repository/revisions/2/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2', :format => 'raw'
234 should_route :get, "/projects/redmine/repository/revisions/2/raw/path/to/file.c", :controller => 'repositories', :action => 'entry', :id => 'redmine', :path => %w[path to file.c], :rev => '2', :format => 'raw'
235 should_route :get, "/projects/redmine/repository/annotate/path/to/file.c", :controller => 'repositories', :action => 'annotate', :id => 'redmine', :path => %w[path to file.c]
235 should_route :get, "/projects/redmine/repository/annotate/path/to/file.c", :controller => 'repositories', :action => 'annotate', :id => 'redmine', :path => %w[path to file.c]
236 should_route :get, "/projects/redmine/repository/changes/path/to/file.c", :controller => 'repositories', :action => 'changes', :id => 'redmine', :path => %w[path to file.c]
236 should_route :get, "/projects/redmine/repository/changes/path/to/file.c", :controller => 'repositories', :action => 'changes', :id => 'redmine', :path => %w[path to file.c]
237 should_route :get, "/projects/redmine/repository/statistics", :controller => 'repositories', :action => 'stats', :id => 'redmine'
237 should_route :get, "/projects/redmine/repository/statistics", :controller => 'repositories', :action => 'stats', :id => 'redmine'
238
238
239
239
240 should_route :post, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
240 should_route :post, "/projects/redmine/repository/edit", :controller => 'repositories', :action => 'edit', :id => 'redmine'
241 end
241 end
242
242
243 context "timelogs (global)" do
243 context "timelogs (global)" do
244 should_route :get, "/time_entries", :controller => 'timelog', :action => 'index'
244 should_route :get, "/time_entries", :controller => 'timelog', :action => 'index'
245 should_route :get, "/time_entries.csv", :controller => 'timelog', :action => 'index', :format => 'csv'
245 should_route :get, "/time_entries.csv", :controller => 'timelog', :action => 'index', :format => 'csv'
246 should_route :get, "/time_entries.atom", :controller => 'timelog', :action => 'index', :format => 'atom'
246 should_route :get, "/time_entries.atom", :controller => 'timelog', :action => 'index', :format => 'atom'
247 should_route :get, "/time_entries/new", :controller => 'timelog', :action => 'new'
247 should_route :get, "/time_entries/new", :controller => 'timelog', :action => 'new'
248 should_route :get, "/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22'
248 should_route :get, "/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22'
249
249
250 should_route :post, "/time_entries", :controller => 'timelog', :action => 'create'
250 should_route :post, "/time_entries", :controller => 'timelog', :action => 'create'
251
251
252 should_route :put, "/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22'
252 should_route :put, "/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22'
253
253
254 should_route :delete, "/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55'
254 should_route :delete, "/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55'
255 end
255 end
256
256
257 context "timelogs (scoped under project)" do
257 context "timelogs (scoped under project)" do
258 should_route :get, "/projects/567/time_entries", :controller => 'timelog', :action => 'index', :project_id => '567'
258 should_route :get, "/projects/567/time_entries", :controller => 'timelog', :action => 'index', :project_id => '567'
259 should_route :get, "/projects/567/time_entries.csv", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'csv'
259 should_route :get, "/projects/567/time_entries.csv", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'csv'
260 should_route :get, "/projects/567/time_entries.atom", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'atom'
260 should_route :get, "/projects/567/time_entries.atom", :controller => 'timelog', :action => 'index', :project_id => '567', :format => 'atom'
261 should_route :get, "/projects/567/time_entries/new", :controller => 'timelog', :action => 'new', :project_id => '567'
261 should_route :get, "/projects/567/time_entries/new", :controller => 'timelog', :action => 'new', :project_id => '567'
262 should_route :get, "/projects/567/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :project_id => '567'
262 should_route :get, "/projects/567/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :project_id => '567'
263
263
264 should_route :post, "/projects/567/time_entries", :controller => 'timelog', :action => 'create', :project_id => '567'
264 should_route :post, "/projects/567/time_entries", :controller => 'timelog', :action => 'create', :project_id => '567'
265
265
266 should_route :put, "/projects/567/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :project_id => '567'
266 should_route :put, "/projects/567/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :project_id => '567'
267
267
268 should_route :delete, "/projects/567/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :project_id => '567'
268 should_route :delete, "/projects/567/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :project_id => '567'
269 end
269 end
270
270
271 context "timelogs (scoped under issues)" do
271 context "timelogs (scoped under issues)" do
272 should_route :get, "/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234'
272 should_route :get, "/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234'
273 should_route :get, "/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'csv'
273 should_route :get, "/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'csv'
274 should_route :get, "/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'atom'
274 should_route :get, "/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :format => 'atom'
275 should_route :get, "/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234'
275 should_route :get, "/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234'
276 should_route :get, "/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234'
276 should_route :get, "/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234'
277
277
278 should_route :post, "/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234'
278 should_route :post, "/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234'
279
279
280 should_route :put, "/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234'
280 should_route :put, "/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234'
281
281
282 should_route :delete, "/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234'
282 should_route :delete, "/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234'
283 end
283 end
284
284
285 context "timelogs (scoped under project and issues)" do
285 context "timelogs (scoped under project and issues)" do
286 should_route :get, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook'
286 should_route :get, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook'
287 should_route :get, "/projects/ecookbook/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'csv'
287 should_route :get, "/projects/ecookbook/issues/234/time_entries.csv", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'csv'
288 should_route :get, "/projects/ecookbook/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'atom'
288 should_route :get, "/projects/ecookbook/issues/234/time_entries.atom", :controller => 'timelog', :action => 'index', :issue_id => '234', :project_id => 'ecookbook', :format => 'atom'
289 should_route :get, "/projects/ecookbook/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234', :project_id => 'ecookbook'
289 should_route :get, "/projects/ecookbook/issues/234/time_entries/new", :controller => 'timelog', :action => 'new', :issue_id => '234', :project_id => 'ecookbook'
290 should_route :get, "/projects/ecookbook/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
290 should_route :get, "/projects/ecookbook/issues/234/time_entries/22/edit", :controller => 'timelog', :action => 'edit', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
291
291
292 should_route :post, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234', :project_id => 'ecookbook'
292 should_route :post, "/projects/ecookbook/issues/234/time_entries", :controller => 'timelog', :action => 'create', :issue_id => '234', :project_id => 'ecookbook'
293
293
294 should_route :put, "/projects/ecookbook/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
294 should_route :put, "/projects/ecookbook/issues/234/time_entries/22", :controller => 'timelog', :action => 'update', :id => '22', :issue_id => '234', :project_id => 'ecookbook'
295
295
296 should_route :delete, "/projects/ecookbook/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234', :project_id => 'ecookbook'
296 should_route :delete, "/projects/ecookbook/issues/234/time_entries/55", :controller => 'timelog', :action => 'destroy', :id => '55', :issue_id => '234', :project_id => 'ecookbook'
297 end
297 end
298
298
299 context "time_entry_reports" do
299 context "time_entry_reports" do
300 should_route :get, "/time_entries/report", :controller => 'time_entry_reports', :action => 'report'
300 should_route :get, "/time_entries/report", :controller => 'time_entry_reports', :action => 'report'
301 should_route :get, "/projects/567/time_entries/report", :controller => 'time_entry_reports', :action => 'report', :project_id => '567'
301 should_route :get, "/projects/567/time_entries/report", :controller => 'time_entry_reports', :action => 'report', :project_id => '567'
302 should_route :get, "/projects/567/time_entries/report.csv", :controller => 'time_entry_reports', :action => 'report', :project_id => '567', :format => 'csv'
302 should_route :get, "/projects/567/time_entries/report.csv", :controller => 'time_entry_reports', :action => 'report', :project_id => '567', :format => 'csv'
303 end
303 end
304
304
305 context "users" do
305 context "users" do
306 should_route :get, "/users", :controller => 'users', :action => 'index'
306 should_route :get, "/users", :controller => 'users', :action => 'index'
307 should_route :get, "/users.xml", :controller => 'users', :action => 'index', :format => 'xml'
307 should_route :get, "/users.xml", :controller => 'users', :action => 'index', :format => 'xml'
308 should_route :get, "/users/44", :controller => 'users', :action => 'show', :id => '44'
308 should_route :get, "/users/44", :controller => 'users', :action => 'show', :id => '44'
309 should_route :get, "/users/44.xml", :controller => 'users', :action => 'show', :id => '44', :format => 'xml'
309 should_route :get, "/users/44.xml", :controller => 'users', :action => 'show', :id => '44', :format => 'xml'
310 should_route :get, "/users/current", :controller => 'users', :action => 'show', :id => 'current'
310 should_route :get, "/users/current", :controller => 'users', :action => 'show', :id => 'current'
311 should_route :get, "/users/current.xml", :controller => 'users', :action => 'show', :id => 'current', :format => 'xml'
311 should_route :get, "/users/current.xml", :controller => 'users', :action => 'show', :id => 'current', :format => 'xml'
312 should_route :get, "/users/new", :controller => 'users', :action => 'new'
312 should_route :get, "/users/new", :controller => 'users', :action => 'new'
313 should_route :get, "/users/444/edit", :controller => 'users', :action => 'edit', :id => '444'
313 should_route :get, "/users/444/edit", :controller => 'users', :action => 'edit', :id => '444'
314 should_route :get, "/users/222/edit/membership", :controller => 'users', :action => 'edit', :id => '222', :tab => 'membership'
314 should_route :get, "/users/222/edit/membership", :controller => 'users', :action => 'edit', :id => '222', :tab => 'membership'
315
315
316 should_route :post, "/users", :controller => 'users', :action => 'create'
316 should_route :post, "/users", :controller => 'users', :action => 'create'
317 should_route :post, "/users.xml", :controller => 'users', :action => 'create', :format => 'xml'
317 should_route :post, "/users.xml", :controller => 'users', :action => 'create', :format => 'xml'
318 should_route :post, "/users/123/memberships", :controller => 'users', :action => 'edit_membership', :id => '123'
318 should_route :post, "/users/123/memberships", :controller => 'users', :action => 'edit_membership', :id => '123'
319 should_route :post, "/users/123/memberships/55", :controller => 'users', :action => 'edit_membership', :id => '123', :membership_id => '55'
319 should_route :post, "/users/123/memberships/55", :controller => 'users', :action => 'edit_membership', :id => '123', :membership_id => '55'
320 should_route :post, "/users/567/memberships/12/destroy", :controller => 'users', :action => 'destroy_membership', :id => '567', :membership_id => '12'
320 should_route :post, "/users/567/memberships/12/destroy", :controller => 'users', :action => 'destroy_membership', :id => '567', :membership_id => '12'
321
321
322 should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444'
322 should_route :put, "/users/444", :controller => 'users', :action => 'update', :id => '444'
323 should_route :put, "/users/444.xml", :controller => 'users', :action => 'update', :id => '444', :format => 'xml'
323 should_route :put, "/users/444.xml", :controller => 'users', :action => 'update', :id => '444', :format => 'xml'
324
324
325 should_route :delete, "/users/44", :controller => 'users', :action => 'destroy', :id => '44'
325 should_route :delete, "/users/44", :controller => 'users', :action => 'destroy', :id => '44'
326 should_route :delete, "/users/44.xml", :controller => 'users', :action => 'destroy', :id => '44', :format => 'xml'
326 should_route :delete, "/users/44.xml", :controller => 'users', :action => 'destroy', :id => '44', :format => 'xml'
327 end
327 end
328
328
329 # TODO: should they all be scoped under /projects/:project_id ?
330 context "versions" do
329 context "versions" do
330 # /projects/foo/versions is /projects/foo/roadmap
331 should_route :get, "/projects/foo/versions.xml", :controller => 'versions', :action => 'index', :project_id => 'foo', :format => 'xml'
332 should_route :get, "/projects/foo/versions.json", :controller => 'versions', :action => 'index', :project_id => 'foo', :format => 'json'
333
331 should_route :get, "/projects/foo/versions/new", :controller => 'versions', :action => 'new', :project_id => 'foo'
334 should_route :get, "/projects/foo/versions/new", :controller => 'versions', :action => 'new', :project_id => 'foo'
332 should_route :get, "/versions/show/1", :controller => 'versions', :action => 'show', :id => '1'
335
333 should_route :get, "/versions/edit/1", :controller => 'versions', :action => 'edit', :id => '1'
334
335 should_route :post, "/projects/foo/versions", :controller => 'versions', :action => 'create', :project_id => 'foo'
336 should_route :post, "/projects/foo/versions", :controller => 'versions', :action => 'create', :project_id => 'foo'
336 should_route :post, "/versions/update/1", :controller => 'versions', :action => 'update', :id => '1'
337 should_route :post, "/projects/foo/versions.xml", :controller => 'versions', :action => 'create', :project_id => 'foo', :format => 'xml'
337
338 should_route :post, "/projects/foo/versions.json", :controller => 'versions', :action => 'create', :project_id => 'foo', :format => 'json'
338 should_route :delete, "/versions/destroy/1", :controller => 'versions', :action => 'destroy', :id => '1'
339
340 should_route :get, "/projects/foo/versions/1", :controller => 'versions', :action => 'show', :project_id => 'foo', :id => '1'
341 should_route :get, "/projects/foo/versions/1.xml", :controller => 'versions', :action => 'show', :project_id => 'foo', :id => '1', :format => 'xml'
342 should_route :get, "/projects/foo/versions/1.json", :controller => 'versions', :action => 'show', :project_id => 'foo', :id => '1', :format => 'json'
343
344 should_route :get, "/projects/foo/versions/1/edit", :controller => 'versions', :action => 'edit', :project_id => 'foo', :id => '1'
345
346 should_route :put, "/projects/foo/versions/1", :controller => 'versions', :action => 'update', :project_id => 'foo', :id => '1'
347 should_route :put, "/projects/foo/versions/1.xml", :controller => 'versions', :action => 'update', :project_id => 'foo', :id => '1', :format => 'xml'
348 should_route :put, "/projects/foo/versions/1.json", :controller => 'versions', :action => 'update', :project_id => 'foo', :id => '1', :format => 'json'
349
350 should_route :delete, "/projects/foo/versions/1", :controller => 'versions', :action => 'destroy', :project_id => 'foo', :id => '1'
351 should_route :delete, "/projects/foo/versions/1.xml", :controller => 'versions', :action => 'destroy', :project_id => 'foo', :id => '1', :format => 'xml'
352 should_route :delete, "/projects/foo/versions/1.json", :controller => 'versions', :action => 'destroy', :project_id => 'foo', :id => '1', :format => 'json'
353
354 should_route :put, "/projects/foo/versions/close_completed", :controller => 'versions', :action => 'close_completed', :project_id => 'foo'
355 should_route :post, "/projects/foo/versions/1/status_by", :controller => 'versions', :action => 'status_by', :project_id => 'foo', :id => '1'
339 end
356 end
340
357
341 context "wiki (singular, project's pages)" do
358 context "wiki (singular, project's pages)" do
342 should_route :get, "/projects/567/wiki", :controller => 'wiki', :action => 'show', :project_id => '567'
359 should_route :get, "/projects/567/wiki", :controller => 'wiki', :action => 'show', :project_id => '567'
343 should_route :get, "/projects/567/wiki/lalala", :controller => 'wiki', :action => 'show', :project_id => '567', :id => 'lalala'
360 should_route :get, "/projects/567/wiki/lalala", :controller => 'wiki', :action => 'show', :project_id => '567', :id => 'lalala'
344 should_route :get, "/projects/567/wiki/my_page/edit", :controller => 'wiki', :action => 'edit', :project_id => '567', :id => 'my_page'
361 should_route :get, "/projects/567/wiki/my_page/edit", :controller => 'wiki', :action => 'edit', :project_id => '567', :id => 'my_page'
345 should_route :get, "/projects/1/wiki/CookBook_documentation/history", :controller => 'wiki', :action => 'history', :project_id => '1', :id => 'CookBook_documentation'
362 should_route :get, "/projects/1/wiki/CookBook_documentation/history", :controller => 'wiki', :action => 'history', :project_id => '1', :id => 'CookBook_documentation'
346 should_route :get, "/projects/1/wiki/CookBook_documentation/diff", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation'
363 should_route :get, "/projects/1/wiki/CookBook_documentation/diff", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation'
347 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
364 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
348 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2/vs/1", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2', :version_from => '1'
365 should_route :get, "/projects/1/wiki/CookBook_documentation/diff/2/vs/1", :controller => 'wiki', :action => 'diff', :project_id => '1', :id => 'CookBook_documentation', :version => '2', :version_from => '1'
349 should_route :get, "/projects/1/wiki/CookBook_documentation/annotate/2", :controller => 'wiki', :action => 'annotate', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
366 should_route :get, "/projects/1/wiki/CookBook_documentation/annotate/2", :controller => 'wiki', :action => 'annotate', :project_id => '1', :id => 'CookBook_documentation', :version => '2'
350 should_route :get, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
367 should_route :get, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
351 should_route :get, "/projects/567/wiki/index", :controller => 'wiki', :action => 'index', :project_id => '567'
368 should_route :get, "/projects/567/wiki/index", :controller => 'wiki', :action => 'index', :project_id => '567'
352 should_route :get, "/projects/567/wiki/date_index", :controller => 'wiki', :action => 'date_index', :project_id => '567'
369 should_route :get, "/projects/567/wiki/date_index", :controller => 'wiki', :action => 'date_index', :project_id => '567'
353 should_route :get, "/projects/567/wiki/export", :controller => 'wiki', :action => 'export', :project_id => '567'
370 should_route :get, "/projects/567/wiki/export", :controller => 'wiki', :action => 'export', :project_id => '567'
354
371
355 should_route :post, "/projects/567/wiki/CookBook_documentation/preview", :controller => 'wiki', :action => 'preview', :project_id => '567', :id => 'CookBook_documentation'
372 should_route :post, "/projects/567/wiki/CookBook_documentation/preview", :controller => 'wiki', :action => 'preview', :project_id => '567', :id => 'CookBook_documentation'
356 should_route :post, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
373 should_route :post, "/projects/22/wiki/ladida/rename", :controller => 'wiki', :action => 'rename', :project_id => '22', :id => 'ladida'
357 should_route :post, "/projects/22/wiki/ladida/protect", :controller => 'wiki', :action => 'protect', :project_id => '22', :id => 'ladida'
374 should_route :post, "/projects/22/wiki/ladida/protect", :controller => 'wiki', :action => 'protect', :project_id => '22', :id => 'ladida'
358 should_route :post, "/projects/22/wiki/ladida/add_attachment", :controller => 'wiki', :action => 'add_attachment', :project_id => '22', :id => 'ladida'
375 should_route :post, "/projects/22/wiki/ladida/add_attachment", :controller => 'wiki', :action => 'add_attachment', :project_id => '22', :id => 'ladida'
359
376
360 should_route :put, "/projects/567/wiki/my_page", :controller => 'wiki', :action => 'update', :project_id => '567', :id => 'my_page'
377 should_route :put, "/projects/567/wiki/my_page", :controller => 'wiki', :action => 'update', :project_id => '567', :id => 'my_page'
361
378
362 should_route :delete, "/projects/22/wiki/ladida", :controller => 'wiki', :action => 'destroy', :project_id => '22', :id => 'ladida'
379 should_route :delete, "/projects/22/wiki/ladida", :controller => 'wiki', :action => 'destroy', :project_id => '22', :id => 'ladida'
363 end
380 end
364
381
365 context "wikis (plural, admin setup)" do
382 context "wikis (plural, admin setup)" do
366 should_route :get, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
383 should_route :get, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
367
384
368 should_route :post, "/projects/ladida/wiki", :controller => 'wikis', :action => 'edit', :id => 'ladida'
385 should_route :post, "/projects/ladida/wiki", :controller => 'wikis', :action => 'edit', :id => 'ladida'
369 should_route :post, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
386 should_route :post, "/projects/ladida/wiki/destroy", :controller => 'wikis', :action => 'destroy', :id => 'ladida'
370 end
387 end
371
388
372 context "administration panel" do
389 context "administration panel" do
373 should_route :get, "/admin/projects", :controller => 'admin', :action => 'projects'
390 should_route :get, "/admin/projects", :controller => 'admin', :action => 'projects'
374 end
391 end
375 end
392 end
@@ -1,234 +1,235
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class VersionTest < ActiveSupport::TestCase
20 class VersionTest < ActiveSupport::TestCase
21 fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions
21 fixtures :projects, :users, :issues, :issue_statuses, :trackers, :enumerations, :versions
22
22
23 def setup
23 def setup
24 end
24 end
25
25
26 def test_create
26 def test_create
27 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
27 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '2011-03-25')
28 assert v.save
28 assert v.save
29 assert_equal 'open', v.status
29 assert_equal 'open', v.status
30 assert_equal 'none', v.sharing
30 end
31 end
31
32
32 def test_invalid_effective_date_validation
33 def test_invalid_effective_date_validation
33 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
34 v = Version.new(:project => Project.find(1), :name => '1.1', :effective_date => '99999-01-01')
34 assert !v.save
35 assert !v.save
35 assert_equal I18n.translate('activerecord.errors.messages.not_a_date'), v.errors.on(:effective_date)
36 assert_equal I18n.translate('activerecord.errors.messages.not_a_date'), v.errors.on(:effective_date)
36 end
37 end
37
38
38 def test_progress_should_be_0_with_no_assigned_issues
39 def test_progress_should_be_0_with_no_assigned_issues
39 project = Project.find(1)
40 project = Project.find(1)
40 v = Version.create!(:project => project, :name => 'Progress')
41 v = Version.create!(:project => project, :name => 'Progress')
41 assert_equal 0, v.completed_pourcent
42 assert_equal 0, v.completed_pourcent
42 assert_equal 0, v.closed_pourcent
43 assert_equal 0, v.closed_pourcent
43 end
44 end
44
45
45 def test_progress_should_be_0_with_unbegun_assigned_issues
46 def test_progress_should_be_0_with_unbegun_assigned_issues
46 project = Project.find(1)
47 project = Project.find(1)
47 v = Version.create!(:project => project, :name => 'Progress')
48 v = Version.create!(:project => project, :name => 'Progress')
48 add_issue(v)
49 add_issue(v)
49 add_issue(v, :done_ratio => 0)
50 add_issue(v, :done_ratio => 0)
50 assert_progress_equal 0, v.completed_pourcent
51 assert_progress_equal 0, v.completed_pourcent
51 assert_progress_equal 0, v.closed_pourcent
52 assert_progress_equal 0, v.closed_pourcent
52 end
53 end
53
54
54 def test_progress_should_be_100_with_closed_assigned_issues
55 def test_progress_should_be_100_with_closed_assigned_issues
55 project = Project.find(1)
56 project = Project.find(1)
56 status = IssueStatus.find(:first, :conditions => {:is_closed => true})
57 status = IssueStatus.find(:first, :conditions => {:is_closed => true})
57 v = Version.create!(:project => project, :name => 'Progress')
58 v = Version.create!(:project => project, :name => 'Progress')
58 add_issue(v, :status => status)
59 add_issue(v, :status => status)
59 add_issue(v, :status => status, :done_ratio => 20)
60 add_issue(v, :status => status, :done_ratio => 20)
60 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
61 add_issue(v, :status => status, :done_ratio => 70, :estimated_hours => 25)
61 add_issue(v, :status => status, :estimated_hours => 15)
62 add_issue(v, :status => status, :estimated_hours => 15)
62 assert_progress_equal 100.0, v.completed_pourcent
63 assert_progress_equal 100.0, v.completed_pourcent
63 assert_progress_equal 100.0, v.closed_pourcent
64 assert_progress_equal 100.0, v.closed_pourcent
64 end
65 end
65
66
66 def test_progress_should_consider_done_ratio_of_open_assigned_issues
67 def test_progress_should_consider_done_ratio_of_open_assigned_issues
67 project = Project.find(1)
68 project = Project.find(1)
68 v = Version.create!(:project => project, :name => 'Progress')
69 v = Version.create!(:project => project, :name => 'Progress')
69 add_issue(v)
70 add_issue(v)
70 add_issue(v, :done_ratio => 20)
71 add_issue(v, :done_ratio => 20)
71 add_issue(v, :done_ratio => 70)
72 add_issue(v, :done_ratio => 70)
72 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent
73 assert_progress_equal (0.0 + 20.0 + 70.0)/3, v.completed_pourcent
73 assert_progress_equal 0, v.closed_pourcent
74 assert_progress_equal 0, v.closed_pourcent
74 end
75 end
75
76
76 def test_progress_should_consider_closed_issues_as_completed
77 def test_progress_should_consider_closed_issues_as_completed
77 project = Project.find(1)
78 project = Project.find(1)
78 v = Version.create!(:project => project, :name => 'Progress')
79 v = Version.create!(:project => project, :name => 'Progress')
79 add_issue(v)
80 add_issue(v)
80 add_issue(v, :done_ratio => 20)
81 add_issue(v, :done_ratio => 20)
81 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
82 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
82 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent
83 assert_progress_equal (0.0 + 20.0 + 100.0)/3, v.completed_pourcent
83 assert_progress_equal (100.0)/3, v.closed_pourcent
84 assert_progress_equal (100.0)/3, v.closed_pourcent
84 end
85 end
85
86
86 def test_progress_should_consider_estimated_hours_to_weigth_issues
87 def test_progress_should_consider_estimated_hours_to_weigth_issues
87 project = Project.find(1)
88 project = Project.find(1)
88 v = Version.create!(:project => project, :name => 'Progress')
89 v = Version.create!(:project => project, :name => 'Progress')
89 add_issue(v, :estimated_hours => 10)
90 add_issue(v, :estimated_hours => 10)
90 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
91 add_issue(v, :estimated_hours => 20, :done_ratio => 30)
91 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
92 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
92 add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
93 add_issue(v, :estimated_hours => 25, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
93 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent
94 assert_progress_equal (10.0*0 + 20.0*0.3 + 40*0.1 + 25.0*1)/95.0*100, v.completed_pourcent
94 assert_progress_equal 25.0/95.0*100, v.closed_pourcent
95 assert_progress_equal 25.0/95.0*100, v.closed_pourcent
95 end
96 end
96
97
97 def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
98 def test_progress_should_consider_average_estimated_hours_to_weigth_unestimated_issues
98 project = Project.find(1)
99 project = Project.find(1)
99 v = Version.create!(:project => project, :name => 'Progress')
100 v = Version.create!(:project => project, :name => 'Progress')
100 add_issue(v, :done_ratio => 20)
101 add_issue(v, :done_ratio => 20)
101 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
102 add_issue(v, :status => IssueStatus.find(:first, :conditions => {:is_closed => true}))
102 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
103 add_issue(v, :estimated_hours => 10, :done_ratio => 30)
103 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
104 add_issue(v, :estimated_hours => 40, :done_ratio => 10)
104 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_pourcent
105 assert_progress_equal (25.0*0.2 + 25.0*1 + 10.0*0.3 + 40.0*0.1)/100.0*100, v.completed_pourcent
105 assert_progress_equal 25.0/100.0*100, v.closed_pourcent
106 assert_progress_equal 25.0/100.0*100, v.closed_pourcent
106 end
107 end
107
108
108 context "#behind_schedule?" do
109 context "#behind_schedule?" do
109 setup do
110 setup do
110 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
111 ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests
111 @project = Project.generate!(:identifier => 'test0')
112 @project = Project.generate!(:identifier => 'test0')
112 @project.trackers << Tracker.generate!
113 @project.trackers << Tracker.generate!
113
114
114 @version = Version.generate!(:project => @project, :effective_date => nil)
115 @version = Version.generate!(:project => @project, :effective_date => nil)
115 end
116 end
116
117
117 should "be false if there are no issues assigned" do
118 should "be false if there are no issues assigned" do
118 @version.update_attribute(:effective_date, Date.yesterday)
119 @version.update_attribute(:effective_date, Date.yesterday)
119 assert_equal false, @version.behind_schedule?
120 assert_equal false, @version.behind_schedule?
120 end
121 end
121
122
122 should "be false if there is no effective_date" do
123 should "be false if there is no effective_date" do
123 assert_equal false, @version.behind_schedule?
124 assert_equal false, @version.behind_schedule?
124 end
125 end
125
126
126 should "be false if all of the issues are ahead of schedule" do
127 should "be false if all of the issues are ahead of schedule" do
127 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
128 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
128 @version.fixed_issues = [
129 @version.fixed_issues = [
129 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60), # 14 day span, 60% done, 50% time left
130 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60), # 14 day span, 60% done, 50% time left
130 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
131 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60) # 14 day span, 60% done, 50% time left
131 ]
132 ]
132 assert_equal 60, @version.completed_pourcent
133 assert_equal 60, @version.completed_pourcent
133 assert_equal false, @version.behind_schedule?
134 assert_equal false, @version.behind_schedule?
134 end
135 end
135
136
136 should "be true if any of the issues are behind schedule" do
137 should "be true if any of the issues are behind schedule" do
137 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
138 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
138 @version.fixed_issues = [
139 @version.fixed_issues = [
139 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60), # 14 day span, 60% done, 50% time left
140 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 60), # 14 day span, 60% done, 50% time left
140 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
141 Issue.generate_for_project!(@project, :start_date => 7.days.ago, :done_ratio => 20) # 14 day span, 20% done, 50% time left
141 ]
142 ]
142 assert_equal 40, @version.completed_pourcent
143 assert_equal 40, @version.completed_pourcent
143 assert_equal true, @version.behind_schedule?
144 assert_equal true, @version.behind_schedule?
144 end
145 end
145
146
146 should "be false if all of the issues are complete" do
147 should "be false if all of the issues are complete" do
147 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
148 @version.update_attribute(:effective_date, 7.days.from_now.to_date)
148 @version.fixed_issues = [
149 @version.fixed_issues = [
149 Issue.generate_for_project!(@project, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)), # 7 day span
150 Issue.generate_for_project!(@project, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)), # 7 day span
150 Issue.generate_for_project!(@project, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
151 Issue.generate_for_project!(@project, :start_date => 14.days.ago, :done_ratio => 100, :status => IssueStatus.find(5)) # 7 day span
151 ]
152 ]
152 assert_equal 100, @version.completed_pourcent
153 assert_equal 100, @version.completed_pourcent
153 assert_equal false, @version.behind_schedule?
154 assert_equal false, @version.behind_schedule?
154
155
155 end
156 end
156 end
157 end
157
158
158 context "#estimated_hours" do
159 context "#estimated_hours" do
159 setup do
160 setup do
160 @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
161 @version = Version.create!(:project_id => 1, :name => '#estimated_hours')
161 end
162 end
162
163
163 should "return 0 with no assigned issues" do
164 should "return 0 with no assigned issues" do
164 assert_equal 0, @version.estimated_hours
165 assert_equal 0, @version.estimated_hours
165 end
166 end
166
167
167 should "return 0 with no estimated hours" do
168 should "return 0 with no estimated hours" do
168 add_issue(@version)
169 add_issue(@version)
169 assert_equal 0, @version.estimated_hours
170 assert_equal 0, @version.estimated_hours
170 end
171 end
171
172
172 should "return the sum of estimated hours" do
173 should "return the sum of estimated hours" do
173 add_issue(@version, :estimated_hours => 2.5)
174 add_issue(@version, :estimated_hours => 2.5)
174 add_issue(@version, :estimated_hours => 5)
175 add_issue(@version, :estimated_hours => 5)
175 assert_equal 7.5, @version.estimated_hours
176 assert_equal 7.5, @version.estimated_hours
176 end
177 end
177
178
178 should "return the sum of leaves estimated hours" do
179 should "return the sum of leaves estimated hours" do
179 parent = add_issue(@version)
180 parent = add_issue(@version)
180 add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
181 add_issue(@version, :estimated_hours => 2.5, :parent_issue_id => parent.id)
181 add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
182 add_issue(@version, :estimated_hours => 5, :parent_issue_id => parent.id)
182 assert_equal 7.5, @version.estimated_hours
183 assert_equal 7.5, @version.estimated_hours
183 end
184 end
184 end
185 end
185
186
186 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
187 test "should update all issue's fixed_version associations in case the hierarchy changed XXX" do
187 User.current = User.find(1) # Need the admin's permissions
188 User.current = User.find(1) # Need the admin's permissions
188
189
189 @version = Version.find(7)
190 @version = Version.find(7)
190 # Separate hierarchy
191 # Separate hierarchy
191 project_1_issue = Issue.find(1)
192 project_1_issue = Issue.find(1)
192 project_1_issue.fixed_version = @version
193 project_1_issue.fixed_version = @version
193 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
194 assert project_1_issue.save, project_1_issue.errors.full_messages.to_s
194
195
195 project_5_issue = Issue.find(6)
196 project_5_issue = Issue.find(6)
196 project_5_issue.fixed_version = @version
197 project_5_issue.fixed_version = @version
197 assert project_5_issue.save
198 assert project_5_issue.save
198
199
199 # Project
200 # Project
200 project_2_issue = Issue.find(4)
201 project_2_issue = Issue.find(4)
201 project_2_issue.fixed_version = @version
202 project_2_issue.fixed_version = @version
202 assert project_2_issue.save
203 assert project_2_issue.save
203
204
204 # Update the sharing
205 # Update the sharing
205 @version.sharing = 'none'
206 @version.sharing = 'none'
206 assert @version.save
207 assert @version.save
207
208
208 # Project 1 now out of the shared scope
209 # Project 1 now out of the shared scope
209 project_1_issue.reload
210 project_1_issue.reload
210 assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
211 assert_equal nil, project_1_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
211
212
212 # Project 5 now out of the shared scope
213 # Project 5 now out of the shared scope
213 project_5_issue.reload
214 project_5_issue.reload
214 assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
215 assert_equal nil, project_5_issue.fixed_version, "Fixed version is still set after changing the Version's sharing"
215
216
216 # Project 2 issue remains
217 # Project 2 issue remains
217 project_2_issue.reload
218 project_2_issue.reload
218 assert_equal @version, project_2_issue.fixed_version
219 assert_equal @version, project_2_issue.fixed_version
219 end
220 end
220
221
221 private
222 private
222
223
223 def add_issue(version, attributes={})
224 def add_issue(version, attributes={})
224 Issue.create!({:project => version.project,
225 Issue.create!({:project => version.project,
225 :fixed_version => version,
226 :fixed_version => version,
226 :subject => 'Test',
227 :subject => 'Test',
227 :author => User.find(:first),
228 :author => User.find(:first),
228 :tracker => version.project.trackers.find(:first)}.merge(attributes))
229 :tracker => version.project.trackers.find(:first)}.merge(attributes))
229 end
230 end
230
231
231 def assert_progress_equal(expected_float, actual_float, message="")
232 def assert_progress_equal(expected_float, actual_float, message="")
232 assert_in_delta(expected_float, actual_float, 0.000001, message="")
233 assert_in_delta(expected_float, actual_float, 0.000001, message="")
233 end
234 end
234 end
235 end
General Comments 0
You need to be logged in to leave comments. Login now