##// END OF EJS Templates
FIxed: inline images not displayed in atom feeds (#3391)....
Jean-Philippe Lang -
r2669:c082cfc90ef8
parent child
Show More
@@ -1,31 +1,31
1 xml.instruct!
1 xml.instruct!
2 xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
2 xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3 xml.title truncate_single_line(@title, :length => 100)
3 xml.title truncate_single_line(@title, :length => 100)
4 xml.link "rel" => "self", "href" => url_for(params.merge(:only_path => false))
4 xml.link "rel" => "self", "href" => url_for(params.merge(:only_path => false))
5 xml.link "rel" => "alternate", "href" => url_for(params.merge(:only_path => false, :format => nil, :key => nil))
5 xml.link "rel" => "alternate", "href" => url_for(params.merge(:only_path => false, :format => nil, :key => nil))
6 xml.id url_for(:controller => 'welcome', :only_path => false)
6 xml.id url_for(:controller => 'welcome', :only_path => false)
7 xml.updated((@items.first ? @items.first.event_datetime : Time.now).xmlschema)
7 xml.updated((@items.first ? @items.first.event_datetime : Time.now).xmlschema)
8 xml.author { xml.name "#{Setting.app_title}" }
8 xml.author { xml.name "#{Setting.app_title}" }
9 xml.generator(:uri => Redmine::Info.url) { xml.text! Redmine::Info.app_name; }
9 xml.generator(:uri => Redmine::Info.url) { xml.text! Redmine::Info.app_name; }
10 @items.each do |item|
10 @items.each do |item|
11 xml.entry do
11 xml.entry do
12 url = url_for(item.event_url(:only_path => false))
12 url = url_for(item.event_url(:only_path => false))
13 if @project
13 if @project
14 xml.title truncate_single_line(item.event_title, :length => 100)
14 xml.title truncate_single_line(item.event_title, :length => 100)
15 else
15 else
16 xml.title truncate_single_line("#{item.project} - #{item.event_title}", :length => 100)
16 xml.title truncate_single_line("#{item.project} - #{item.event_title}", :length => 100)
17 end
17 end
18 xml.link "rel" => "alternate", "href" => url
18 xml.link "rel" => "alternate", "href" => url
19 xml.id url
19 xml.id url
20 xml.updated item.event_datetime.xmlschema
20 xml.updated item.event_datetime.xmlschema
21 author = item.event_author if item.respond_to?(:event_author)
21 author = item.event_author if item.respond_to?(:event_author)
22 xml.author do
22 xml.author do
23 xml.name(author)
23 xml.name(author)
24 xml.email(author.mail) if author.is_a?(User) && !author.mail.blank? && !author.pref.hide_mail
24 xml.email(author.mail) if author.is_a?(User) && !author.mail.blank? && !author.pref.hide_mail
25 end if author
25 end if author
26 xml.content "type" => "html" do
26 xml.content "type" => "html" do
27 xml.text! textilizable(item.event_description, :only_path => false)
27 xml.text! textilizable(item, :event_description, :only_path => false)
28 end
28 end
29 end
29 end
30 end
30 end
31 end
31 end
@@ -1,30 +1,30
1 xml.instruct!
1 xml.instruct!
2 xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
2 xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
3 xml.title @title
3 xml.title @title
4 xml.link "rel" => "self", "href" => url_for(:format => 'atom', :key => User.current.rss_key, :only_path => false)
4 xml.link "rel" => "self", "href" => url_for(:format => 'atom', :key => User.current.rss_key, :only_path => false)
5 xml.link "rel" => "alternate", "href" => home_url(:only_path => false)
5 xml.link "rel" => "alternate", "href" => home_url(:only_path => false)
6 xml.id url_for(:controller => 'welcome', :only_path => false)
6 xml.id url_for(:controller => 'welcome', :only_path => false)
7 xml.updated((@journals.first ? @journals.first.event_datetime : Time.now).xmlschema)
7 xml.updated((@journals.first ? @journals.first.event_datetime : Time.now).xmlschema)
8 xml.author { xml.name "#{Setting.app_title}" }
8 xml.author { xml.name "#{Setting.app_title}" }
9 @journals.each do |change|
9 @journals.each do |change|
10 issue = change.issue
10 issue = change.issue
11 xml.entry do
11 xml.entry do
12 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
12 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
13 xml.link "rel" => "alternate", "href" => url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
13 xml.link "rel" => "alternate", "href" => url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
14 xml.id url_for(:controller => 'issues' , :action => 'show', :id => issue, :journal_id => change, :only_path => false)
14 xml.id url_for(:controller => 'issues' , :action => 'show', :id => issue, :journal_id => change, :only_path => false)
15 xml.updated change.created_on.xmlschema
15 xml.updated change.created_on.xmlschema
16 xml.author do
16 xml.author do
17 xml.name change.user.name
17 xml.name change.user.name
18 xml.email(change.user.mail) if change.user.is_a?(User) && !change.user.mail.blank? && !change.user.pref.hide_mail
18 xml.email(change.user.mail) if change.user.is_a?(User) && !change.user.mail.blank? && !change.user.pref.hide_mail
19 end
19 end
20 xml.content "type" => "html" do
20 xml.content "type" => "html" do
21 xml.text! '<ul>'
21 xml.text! '<ul>'
22 change.details.each do |detail|
22 change.details.each do |detail|
23 xml.text! '<li>' + show_detail(detail, false) + '</li>'
23 xml.text! '<li>' + show_detail(detail, false) + '</li>'
24 end
24 end
25 xml.text! '</ul>'
25 xml.text! '</ul>'
26 xml.text! textilizable(change.notes) unless change.notes.blank?
26 xml.text! textilizable(change, :notes, :only_path => false) unless change.notes.blank?
27 end
27 end
28 end
28 end
29 end
29 end
30 end No newline at end of file
30 end
@@ -1,112 +1,124
1 ---
1 ---
2 attachments_001:
2 attachments_001:
3 created_on: 2006-07-19 21:07:27 +02:00
3 created_on: 2006-07-19 21:07:27 +02:00
4 downloads: 0
4 downloads: 0
5 content_type: text/plain
5 content_type: text/plain
6 disk_filename: 060719210727_error281.txt
6 disk_filename: 060719210727_error281.txt
7 container_id: 3
7 container_id: 3
8 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
8 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
9 id: 1
9 id: 1
10 container_type: Issue
10 container_type: Issue
11 filesize: 28
11 filesize: 28
12 filename: error281.txt
12 filename: error281.txt
13 author_id: 2
13 author_id: 2
14 attachments_002:
14 attachments_002:
15 created_on: 2006-07-19 21:07:27 +02:00
15 created_on: 2006-07-19 21:07:27 +02:00
16 downloads: 0
16 downloads: 0
17 content_type: text/plain
17 content_type: text/plain
18 disk_filename: 060719210727_document.txt
18 disk_filename: 060719210727_document.txt
19 container_id: 1
19 container_id: 1
20 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
20 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
21 id: 2
21 id: 2
22 container_type: Document
22 container_type: Document
23 filesize: 28
23 filesize: 28
24 filename: document.txt
24 filename: document.txt
25 author_id: 2
25 author_id: 2
26 attachments_003:
26 attachments_003:
27 created_on: 2006-07-19 21:07:27 +02:00
27 created_on: 2006-07-19 21:07:27 +02:00
28 downloads: 0
28 downloads: 0
29 content_type: image/gif
29 content_type: image/gif
30 disk_filename: 060719210727_logo.gif
30 disk_filename: 060719210727_logo.gif
31 container_id: 4
31 container_id: 4
32 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
32 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
33 id: 3
33 id: 3
34 container_type: WikiPage
34 container_type: WikiPage
35 filesize: 280
35 filesize: 280
36 filename: logo.gif
36 filename: logo.gif
37 description: This is a logo
37 description: This is a logo
38 author_id: 2
38 author_id: 2
39 attachments_004:
39 attachments_004:
40 created_on: 2006-07-19 21:07:27 +02:00
40 created_on: 2006-07-19 21:07:27 +02:00
41 container_type: Issue
41 container_type: Issue
42 container_id: 3
42 container_id: 3
43 downloads: 0
43 downloads: 0
44 disk_filename: 060719210727_source.rb
44 disk_filename: 060719210727_source.rb
45 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
45 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
46 id: 4
46 id: 4
47 filesize: 153
47 filesize: 153
48 filename: source.rb
48 filename: source.rb
49 author_id: 2
49 author_id: 2
50 description: This is a Ruby source file
50 description: This is a Ruby source file
51 content_type: application/x-ruby
51 content_type: application/x-ruby
52 attachments_005:
52 attachments_005:
53 created_on: 2006-07-19 21:07:27 +02:00
53 created_on: 2006-07-19 21:07:27 +02:00
54 container_type: Issue
54 container_type: Issue
55 container_id: 3
55 container_id: 3
56 downloads: 0
56 downloads: 0
57 disk_filename: 060719210727_changeset.diff
57 disk_filename: 060719210727_changeset.diff
58 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
58 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
59 id: 5
59 id: 5
60 filesize: 687
60 filesize: 687
61 filename: changeset.diff
61 filename: changeset.diff
62 author_id: 2
62 author_id: 2
63 content_type: text/x-diff
63 content_type: text/x-diff
64 attachments_006:
64 attachments_006:
65 created_on: 2006-07-19 21:07:27 +02:00
65 created_on: 2006-07-19 21:07:27 +02:00
66 container_type: Issue
66 container_type: Issue
67 container_id: 3
67 container_id: 3
68 downloads: 0
68 downloads: 0
69 disk_filename: 060719210727_archive.zip
69 disk_filename: 060719210727_archive.zip
70 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
70 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
71 id: 6
71 id: 6
72 filesize: 157
72 filesize: 157
73 filename: archive.zip
73 filename: archive.zip
74 author_id: 2
74 author_id: 2
75 content_type: application/octet-stream
75 content_type: application/octet-stream
76 attachments_007:
76 attachments_007:
77 created_on: 2006-07-19 21:07:27 +02:00
77 created_on: 2006-07-19 21:07:27 +02:00
78 container_type: Issue
78 container_type: Issue
79 container_id: 4
79 container_id: 4
80 downloads: 0
80 downloads: 0
81 disk_filename: 060719210727_archive.zip
81 disk_filename: 060719210727_archive.zip
82 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
82 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
83 id: 7
83 id: 7
84 filesize: 157
84 filesize: 157
85 filename: archive.zip
85 filename: archive.zip
86 author_id: 1
86 author_id: 1
87 content_type: application/octet-stream
87 content_type: application/octet-stream
88 attachments_008:
88 attachments_008:
89 created_on: 2006-07-19 21:07:27 +02:00
89 created_on: 2006-07-19 21:07:27 +02:00
90 container_type: Project
90 container_type: Project
91 container_id: 1
91 container_id: 1
92 downloads: 0
92 downloads: 0
93 disk_filename: 060719210727_project_file.zip
93 disk_filename: 060719210727_project_file.zip
94 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
94 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
95 id: 8
95 id: 8
96 filesize: 320
96 filesize: 320
97 filename: project_file.zip
97 filename: project_file.zip
98 author_id: 2
98 author_id: 2
99 content_type: application/octet-stream
99 content_type: application/octet-stream
100 attachments_009:
100 attachments_009:
101 created_on: 2006-07-19 21:07:27 +02:00
101 created_on: 2006-07-19 21:07:27 +02:00
102 container_type: Version
102 container_type: Version
103 container_id: 1
103 container_id: 1
104 downloads: 0
104 downloads: 0
105 disk_filename: 060719210727_version_file.zip
105 disk_filename: 060719210727_version_file.zip
106 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
106 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
107 id: 9
107 id: 9
108 filesize: 452
108 filesize: 452
109 filename: version_file.zip
109 filename: version_file.zip
110 author_id: 2
110 author_id: 2
111 content_type: application/octet-stream
111 content_type: application/octet-stream
112 attachments_010:
113 created_on: 2006-07-19 21:07:27 +02:00
114 container_type: Issue
115 container_id: 2
116 downloads: 0
117 disk_filename: 060719210727_picture.jpg
118 digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
119 id: 10
120 filesize: 452
121 filename: picture.jpg
122 author_id: 2
123 content_type: image/jpeg
112 No newline at end of file
124
@@ -1,16 +1,23
1 ---
1 ---
2 journals_001:
2 journals_001:
3 created_on: <%= 2.days.ago.to_date.to_s(:db) %>
3 created_on: <%= 2.days.ago.to_date.to_s(:db) %>
4 notes: "Journal notes"
4 notes: "Journal notes"
5 id: 1
5 id: 1
6 journalized_type: Issue
6 journalized_type: Issue
7 user_id: 1
7 user_id: 1
8 journalized_id: 1
8 journalized_id: 1
9 journals_002:
9 journals_002:
10 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
10 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
11 notes: "Some notes with Redmine links: #2, r2."
11 notes: "Some notes with Redmine links: #2, r2."
12 id: 2
12 id: 2
13 journalized_type: Issue
13 journalized_type: Issue
14 user_id: 2
14 user_id: 2
15 journalized_id: 1
15 journalized_id: 1
16 journals_003:
17 created_on: <%= 1.days.ago.to_date.to_s(:db) %>
18 notes: "A comment with inline image: !picture.jpg!"
19 id: 3
20 journalized_type: Issue
21 user_id: 2
22 journalized_id: 2
16 No newline at end of file
23
@@ -1,1081 +1,1089
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2008 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.dirname(__FILE__) + '/../test_helper'
18 require File.dirname(__FILE__) + '/../test_helper'
19 require 'issues_controller'
19 require 'issues_controller'
20
20
21 # Re-raise errors caught by the controller.
21 # Re-raise errors caught by the controller.
22 class IssuesController; def rescue_action(e) raise e end; end
22 class IssuesController; def rescue_action(e) raise e end; end
23
23
24 class IssuesControllerTest < Test::Unit::TestCase
24 class IssuesControllerTest < Test::Unit::TestCase
25 fixtures :projects,
25 fixtures :projects,
26 :users,
26 :users,
27 :roles,
27 :roles,
28 :members,
28 :members,
29 :member_roles,
29 :member_roles,
30 :issues,
30 :issues,
31 :issue_statuses,
31 :issue_statuses,
32 :versions,
32 :versions,
33 :trackers,
33 :trackers,
34 :projects_trackers,
34 :projects_trackers,
35 :issue_categories,
35 :issue_categories,
36 :enabled_modules,
36 :enabled_modules,
37 :enumerations,
37 :enumerations,
38 :attachments,
38 :attachments,
39 :workflows,
39 :workflows,
40 :custom_fields,
40 :custom_fields,
41 :custom_values,
41 :custom_values,
42 :custom_fields_trackers,
42 :custom_fields_trackers,
43 :time_entries,
43 :time_entries,
44 :journals,
44 :journals,
45 :journal_details
45 :journal_details
46
46
47 def setup
47 def setup
48 @controller = IssuesController.new
48 @controller = IssuesController.new
49 @request = ActionController::TestRequest.new
49 @request = ActionController::TestRequest.new
50 @response = ActionController::TestResponse.new
50 @response = ActionController::TestResponse.new
51 User.current = nil
51 User.current = nil
52 end
52 end
53
53
54 def test_index_routing
54 def test_index_routing
55 assert_routing(
55 assert_routing(
56 {:method => :get, :path => '/issues'},
56 {:method => :get, :path => '/issues'},
57 :controller => 'issues', :action => 'index'
57 :controller => 'issues', :action => 'index'
58 )
58 )
59 end
59 end
60
60
61 def test_index
61 def test_index
62 Setting.default_language = 'en'
62 Setting.default_language = 'en'
63
63
64 get :index
64 get :index
65 assert_response :success
65 assert_response :success
66 assert_template 'index.rhtml'
66 assert_template 'index.rhtml'
67 assert_not_nil assigns(:issues)
67 assert_not_nil assigns(:issues)
68 assert_nil assigns(:project)
68 assert_nil assigns(:project)
69 assert_tag :tag => 'a', :content => /Can't print recipes/
69 assert_tag :tag => 'a', :content => /Can't print recipes/
70 assert_tag :tag => 'a', :content => /Subproject issue/
70 assert_tag :tag => 'a', :content => /Subproject issue/
71 # private projects hidden
71 # private projects hidden
72 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
72 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
73 assert_no_tag :tag => 'a', :content => /Issue on project 2/
73 assert_no_tag :tag => 'a', :content => /Issue on project 2/
74 # project column
74 # project column
75 assert_tag :tag => 'th', :content => /Project/
75 assert_tag :tag => 'th', :content => /Project/
76 end
76 end
77
77
78 def test_index_should_not_list_issues_when_module_disabled
78 def test_index_should_not_list_issues_when_module_disabled
79 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
79 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
80 get :index
80 get :index
81 assert_response :success
81 assert_response :success
82 assert_template 'index.rhtml'
82 assert_template 'index.rhtml'
83 assert_not_nil assigns(:issues)
83 assert_not_nil assigns(:issues)
84 assert_nil assigns(:project)
84 assert_nil assigns(:project)
85 assert_no_tag :tag => 'a', :content => /Can't print recipes/
85 assert_no_tag :tag => 'a', :content => /Can't print recipes/
86 assert_tag :tag => 'a', :content => /Subproject issue/
86 assert_tag :tag => 'a', :content => /Subproject issue/
87 end
87 end
88
88
89 def test_index_with_project_routing
89 def test_index_with_project_routing
90 assert_routing(
90 assert_routing(
91 {:method => :get, :path => '/projects/23/issues'},
91 {:method => :get, :path => '/projects/23/issues'},
92 :controller => 'issues', :action => 'index', :project_id => '23'
92 :controller => 'issues', :action => 'index', :project_id => '23'
93 )
93 )
94 end
94 end
95
95
96 def test_index_should_not_list_issues_when_module_disabled
96 def test_index_should_not_list_issues_when_module_disabled
97 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
97 EnabledModule.delete_all("name = 'issue_tracking' AND project_id = 1")
98 get :index
98 get :index
99 assert_response :success
99 assert_response :success
100 assert_template 'index.rhtml'
100 assert_template 'index.rhtml'
101 assert_not_nil assigns(:issues)
101 assert_not_nil assigns(:issues)
102 assert_nil assigns(:project)
102 assert_nil assigns(:project)
103 assert_no_tag :tag => 'a', :content => /Can't print recipes/
103 assert_no_tag :tag => 'a', :content => /Can't print recipes/
104 assert_tag :tag => 'a', :content => /Subproject issue/
104 assert_tag :tag => 'a', :content => /Subproject issue/
105 end
105 end
106
106
107 def test_index_with_project_routing
107 def test_index_with_project_routing
108 assert_routing(
108 assert_routing(
109 {:method => :get, :path => 'projects/23/issues'},
109 {:method => :get, :path => 'projects/23/issues'},
110 :controller => 'issues', :action => 'index', :project_id => '23'
110 :controller => 'issues', :action => 'index', :project_id => '23'
111 )
111 )
112 end
112 end
113
113
114 def test_index_with_project
114 def test_index_with_project
115 Setting.display_subprojects_issues = 0
115 Setting.display_subprojects_issues = 0
116 get :index, :project_id => 1
116 get :index, :project_id => 1
117 assert_response :success
117 assert_response :success
118 assert_template 'index.rhtml'
118 assert_template 'index.rhtml'
119 assert_not_nil assigns(:issues)
119 assert_not_nil assigns(:issues)
120 assert_tag :tag => 'a', :content => /Can't print recipes/
120 assert_tag :tag => 'a', :content => /Can't print recipes/
121 assert_no_tag :tag => 'a', :content => /Subproject issue/
121 assert_no_tag :tag => 'a', :content => /Subproject issue/
122 end
122 end
123
123
124 def test_index_with_project_and_subprojects
124 def test_index_with_project_and_subprojects
125 Setting.display_subprojects_issues = 1
125 Setting.display_subprojects_issues = 1
126 get :index, :project_id => 1
126 get :index, :project_id => 1
127 assert_response :success
127 assert_response :success
128 assert_template 'index.rhtml'
128 assert_template 'index.rhtml'
129 assert_not_nil assigns(:issues)
129 assert_not_nil assigns(:issues)
130 assert_tag :tag => 'a', :content => /Can't print recipes/
130 assert_tag :tag => 'a', :content => /Can't print recipes/
131 assert_tag :tag => 'a', :content => /Subproject issue/
131 assert_tag :tag => 'a', :content => /Subproject issue/
132 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
132 assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
133 end
133 end
134
134
135 def test_index_with_project_and_subprojects_should_show_private_subprojects
135 def test_index_with_project_and_subprojects_should_show_private_subprojects
136 @request.session[:user_id] = 2
136 @request.session[:user_id] = 2
137 Setting.display_subprojects_issues = 1
137 Setting.display_subprojects_issues = 1
138 get :index, :project_id => 1
138 get :index, :project_id => 1
139 assert_response :success
139 assert_response :success
140 assert_template 'index.rhtml'
140 assert_template 'index.rhtml'
141 assert_not_nil assigns(:issues)
141 assert_not_nil assigns(:issues)
142 assert_tag :tag => 'a', :content => /Can't print recipes/
142 assert_tag :tag => 'a', :content => /Can't print recipes/
143 assert_tag :tag => 'a', :content => /Subproject issue/
143 assert_tag :tag => 'a', :content => /Subproject issue/
144 assert_tag :tag => 'a', :content => /Issue of a private subproject/
144 assert_tag :tag => 'a', :content => /Issue of a private subproject/
145 end
145 end
146
146
147 def test_index_with_project_routing_formatted
147 def test_index_with_project_routing_formatted
148 assert_routing(
148 assert_routing(
149 {:method => :get, :path => 'projects/23/issues.pdf'},
149 {:method => :get, :path => 'projects/23/issues.pdf'},
150 :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
150 :controller => 'issues', :action => 'index', :project_id => '23', :format => 'pdf'
151 )
151 )
152 assert_routing(
152 assert_routing(
153 {:method => :get, :path => 'projects/23/issues.atom'},
153 {:method => :get, :path => 'projects/23/issues.atom'},
154 :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
154 :controller => 'issues', :action => 'index', :project_id => '23', :format => 'atom'
155 )
155 )
156 end
156 end
157
157
158 def test_index_with_project_and_filter
158 def test_index_with_project_and_filter
159 get :index, :project_id => 1, :set_filter => 1
159 get :index, :project_id => 1, :set_filter => 1
160 assert_response :success
160 assert_response :success
161 assert_template 'index.rhtml'
161 assert_template 'index.rhtml'
162 assert_not_nil assigns(:issues)
162 assert_not_nil assigns(:issues)
163 end
163 end
164
164
165 def test_index_with_query
165 def test_index_with_query
166 get :index, :project_id => 1, :query_id => 5
166 get :index, :project_id => 1, :query_id => 5
167 assert_response :success
167 assert_response :success
168 assert_template 'index.rhtml'
168 assert_template 'index.rhtml'
169 assert_not_nil assigns(:issues)
169 assert_not_nil assigns(:issues)
170 assert_nil assigns(:issue_count_by_group)
170 assert_nil assigns(:issue_count_by_group)
171 end
171 end
172
172
173 def test_index_with_grouped_query
173 def test_index_with_grouped_query
174 get :index, :project_id => 1, :query_id => 6
174 get :index, :project_id => 1, :query_id => 6
175 assert_response :success
175 assert_response :success
176 assert_template 'index.rhtml'
176 assert_template 'index.rhtml'
177 assert_not_nil assigns(:issues)
177 assert_not_nil assigns(:issues)
178 assert_not_nil assigns(:issue_count_by_group)
178 assert_not_nil assigns(:issue_count_by_group)
179 end
179 end
180
180
181 def test_index_csv_with_project
181 def test_index_csv_with_project
182 get :index, :format => 'csv'
182 get :index, :format => 'csv'
183 assert_response :success
183 assert_response :success
184 assert_not_nil assigns(:issues)
184 assert_not_nil assigns(:issues)
185 assert_equal 'text/csv', @response.content_type
185 assert_equal 'text/csv', @response.content_type
186
186
187 get :index, :project_id => 1, :format => 'csv'
187 get :index, :project_id => 1, :format => 'csv'
188 assert_response :success
188 assert_response :success
189 assert_not_nil assigns(:issues)
189 assert_not_nil assigns(:issues)
190 assert_equal 'text/csv', @response.content_type
190 assert_equal 'text/csv', @response.content_type
191 end
191 end
192
192
193 def test_index_formatted
193 def test_index_formatted
194 assert_routing(
194 assert_routing(
195 {:method => :get, :path => 'issues.pdf'},
195 {:method => :get, :path => 'issues.pdf'},
196 :controller => 'issues', :action => 'index', :format => 'pdf'
196 :controller => 'issues', :action => 'index', :format => 'pdf'
197 )
197 )
198 assert_routing(
198 assert_routing(
199 {:method => :get, :path => 'issues.atom'},
199 {:method => :get, :path => 'issues.atom'},
200 :controller => 'issues', :action => 'index', :format => 'atom'
200 :controller => 'issues', :action => 'index', :format => 'atom'
201 )
201 )
202 end
202 end
203
203
204 def test_index_pdf
204 def test_index_pdf
205 get :index, :format => 'pdf'
205 get :index, :format => 'pdf'
206 assert_response :success
206 assert_response :success
207 assert_not_nil assigns(:issues)
207 assert_not_nil assigns(:issues)
208 assert_equal 'application/pdf', @response.content_type
208 assert_equal 'application/pdf', @response.content_type
209
209
210 get :index, :project_id => 1, :format => 'pdf'
210 get :index, :project_id => 1, :format => 'pdf'
211 assert_response :success
211 assert_response :success
212 assert_not_nil assigns(:issues)
212 assert_not_nil assigns(:issues)
213 assert_equal 'application/pdf', @response.content_type
213 assert_equal 'application/pdf', @response.content_type
214
214
215 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
215 get :index, :project_id => 1, :query_id => 6, :format => 'pdf'
216 assert_response :success
216 assert_response :success
217 assert_not_nil assigns(:issues)
217 assert_not_nil assigns(:issues)
218 assert_equal 'application/pdf', @response.content_type
218 assert_equal 'application/pdf', @response.content_type
219 end
219 end
220
220
221 def test_index_sort
221 def test_index_sort
222 get :index, :sort => 'tracker,id:desc'
222 get :index, :sort => 'tracker,id:desc'
223 assert_response :success
223 assert_response :success
224
224
225 sort_params = @request.session['issues_index_sort']
225 sort_params = @request.session['issues_index_sort']
226 assert sort_params.is_a?(String)
226 assert sort_params.is_a?(String)
227 assert_equal 'tracker,id:desc', sort_params
227 assert_equal 'tracker,id:desc', sort_params
228
228
229 issues = assigns(:issues)
229 issues = assigns(:issues)
230 assert_not_nil issues
230 assert_not_nil issues
231 assert !issues.empty?
231 assert !issues.empty?
232 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
232 assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
233 end
233 end
234
234
235 def test_gantt
235 def test_gantt
236 get :gantt, :project_id => 1
236 get :gantt, :project_id => 1
237 assert_response :success
237 assert_response :success
238 assert_template 'gantt.rhtml'
238 assert_template 'gantt.rhtml'
239 assert_not_nil assigns(:gantt)
239 assert_not_nil assigns(:gantt)
240 events = assigns(:gantt).events
240 events = assigns(:gantt).events
241 assert_not_nil events
241 assert_not_nil events
242 # Issue with start and due dates
242 # Issue with start and due dates
243 i = Issue.find(1)
243 i = Issue.find(1)
244 assert_not_nil i.due_date
244 assert_not_nil i.due_date
245 assert events.include?(Issue.find(1))
245 assert events.include?(Issue.find(1))
246 # Issue with without due date but targeted to a version with date
246 # Issue with without due date but targeted to a version with date
247 i = Issue.find(2)
247 i = Issue.find(2)
248 assert_nil i.due_date
248 assert_nil i.due_date
249 assert events.include?(i)
249 assert events.include?(i)
250 end
250 end
251
251
252 def test_cross_project_gantt
252 def test_cross_project_gantt
253 get :gantt
253 get :gantt
254 assert_response :success
254 assert_response :success
255 assert_template 'gantt.rhtml'
255 assert_template 'gantt.rhtml'
256 assert_not_nil assigns(:gantt)
256 assert_not_nil assigns(:gantt)
257 events = assigns(:gantt).events
257 events = assigns(:gantt).events
258 assert_not_nil events
258 assert_not_nil events
259 end
259 end
260
260
261 def test_gantt_export_to_pdf
261 def test_gantt_export_to_pdf
262 get :gantt, :project_id => 1, :format => 'pdf'
262 get :gantt, :project_id => 1, :format => 'pdf'
263 assert_response :success
263 assert_response :success
264 assert_equal 'application/pdf', @response.content_type
264 assert_equal 'application/pdf', @response.content_type
265 assert @response.body.starts_with?('%PDF')
265 assert @response.body.starts_with?('%PDF')
266 assert_not_nil assigns(:gantt)
266 assert_not_nil assigns(:gantt)
267 end
267 end
268
268
269 def test_cross_project_gantt_export_to_pdf
269 def test_cross_project_gantt_export_to_pdf
270 get :gantt, :format => 'pdf'
270 get :gantt, :format => 'pdf'
271 assert_response :success
271 assert_response :success
272 assert_equal 'application/pdf', @response.content_type
272 assert_equal 'application/pdf', @response.content_type
273 assert @response.body.starts_with?('%PDF')
273 assert @response.body.starts_with?('%PDF')
274 assert_not_nil assigns(:gantt)
274 assert_not_nil assigns(:gantt)
275 end
275 end
276
276
277 if Object.const_defined?(:Magick)
277 if Object.const_defined?(:Magick)
278 def test_gantt_image
278 def test_gantt_image
279 get :gantt, :project_id => 1, :format => 'png'
279 get :gantt, :project_id => 1, :format => 'png'
280 assert_response :success
280 assert_response :success
281 assert_equal 'image/png', @response.content_type
281 assert_equal 'image/png', @response.content_type
282 end
282 end
283 else
283 else
284 puts "RMagick not installed. Skipping tests !!!"
284 puts "RMagick not installed. Skipping tests !!!"
285 end
285 end
286
286
287 def test_calendar
287 def test_calendar
288 get :calendar, :project_id => 1
288 get :calendar, :project_id => 1
289 assert_response :success
289 assert_response :success
290 assert_template 'calendar'
290 assert_template 'calendar'
291 assert_not_nil assigns(:calendar)
291 assert_not_nil assigns(:calendar)
292 end
292 end
293
293
294 def test_cross_project_calendar
294 def test_cross_project_calendar
295 get :calendar
295 get :calendar
296 assert_response :success
296 assert_response :success
297 assert_template 'calendar'
297 assert_template 'calendar'
298 assert_not_nil assigns(:calendar)
298 assert_not_nil assigns(:calendar)
299 end
299 end
300
300
301 def test_changes
301 def test_changes
302 get :changes, :project_id => 1
302 get :changes, :project_id => 1
303 assert_response :success
303 assert_response :success
304 assert_not_nil assigns(:journals)
304 assert_not_nil assigns(:journals)
305 assert_equal 'application/atom+xml', @response.content_type
305 assert_equal 'application/atom+xml', @response.content_type
306 end
306 end
307
307
308 def test_show_routing
308 def test_show_routing
309 assert_routing(
309 assert_routing(
310 {:method => :get, :path => '/issues/64'},
310 {:method => :get, :path => '/issues/64'},
311 :controller => 'issues', :action => 'show', :id => '64'
311 :controller => 'issues', :action => 'show', :id => '64'
312 )
312 )
313 end
313 end
314
314
315 def test_show_routing_formatted
315 def test_show_routing_formatted
316 assert_routing(
316 assert_routing(
317 {:method => :get, :path => '/issues/2332.pdf'},
317 {:method => :get, :path => '/issues/2332.pdf'},
318 :controller => 'issues', :action => 'show', :id => '2332', :format => 'pdf'
318 :controller => 'issues', :action => 'show', :id => '2332', :format => 'pdf'
319 )
319 )
320 assert_routing(
320 assert_routing(
321 {:method => :get, :path => '/issues/23123.atom'},
321 {:method => :get, :path => '/issues/23123.atom'},
322 :controller => 'issues', :action => 'show', :id => '23123', :format => 'atom'
322 :controller => 'issues', :action => 'show', :id => '23123', :format => 'atom'
323 )
323 )
324 end
324 end
325
325
326 def test_show_by_anonymous
326 def test_show_by_anonymous
327 get :show, :id => 1
327 get :show, :id => 1
328 assert_response :success
328 assert_response :success
329 assert_template 'show.rhtml'
329 assert_template 'show.rhtml'
330 assert_not_nil assigns(:issue)
330 assert_not_nil assigns(:issue)
331 assert_equal Issue.find(1), assigns(:issue)
331 assert_equal Issue.find(1), assigns(:issue)
332
332
333 # anonymous role is allowed to add a note
333 # anonymous role is allowed to add a note
334 assert_tag :tag => 'form',
334 assert_tag :tag => 'form',
335 :descendant => { :tag => 'fieldset',
335 :descendant => { :tag => 'fieldset',
336 :child => { :tag => 'legend',
336 :child => { :tag => 'legend',
337 :content => /Notes/ } }
337 :content => /Notes/ } }
338 end
338 end
339
339
340 def test_show_by_manager
340 def test_show_by_manager
341 @request.session[:user_id] = 2
341 @request.session[:user_id] = 2
342 get :show, :id => 1
342 get :show, :id => 1
343 assert_response :success
343 assert_response :success
344
344
345 assert_tag :tag => 'form',
345 assert_tag :tag => 'form',
346 :descendant => { :tag => 'fieldset',
346 :descendant => { :tag => 'fieldset',
347 :child => { :tag => 'legend',
347 :child => { :tag => 'legend',
348 :content => /Change properties/ } },
348 :content => /Change properties/ } },
349 :descendant => { :tag => 'fieldset',
349 :descendant => { :tag => 'fieldset',
350 :child => { :tag => 'legend',
350 :child => { :tag => 'legend',
351 :content => /Log time/ } },
351 :content => /Log time/ } },
352 :descendant => { :tag => 'fieldset',
352 :descendant => { :tag => 'fieldset',
353 :child => { :tag => 'legend',
353 :child => { :tag => 'legend',
354 :content => /Notes/ } }
354 :content => /Notes/ } }
355 end
355 end
356
356
357 def test_show_should_not_disclose_relations_to_invisible_issues
357 def test_show_should_not_disclose_relations_to_invisible_issues
358 Setting.cross_project_issue_relations = '1'
358 Setting.cross_project_issue_relations = '1'
359 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
359 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(2), :relation_type => 'relates')
360 # Relation to a private project issue
360 # Relation to a private project issue
361 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
361 IssueRelation.create!(:issue_from => Issue.find(1), :issue_to => Issue.find(4), :relation_type => 'relates')
362
362
363 get :show, :id => 1
363 get :show, :id => 1
364 assert_response :success
364 assert_response :success
365
365
366 assert_tag :div, :attributes => { :id => 'relations' },
366 assert_tag :div, :attributes => { :id => 'relations' },
367 :descendant => { :tag => 'a', :content => /#2$/ }
367 :descendant => { :tag => 'a', :content => /#2$/ }
368 assert_no_tag :div, :attributes => { :id => 'relations' },
368 assert_no_tag :div, :attributes => { :id => 'relations' },
369 :descendant => { :tag => 'a', :content => /#4$/ }
369 :descendant => { :tag => 'a', :content => /#4$/ }
370 end
370 end
371
371
372 def test_show_atom
373 get :show, :id => 2, :format => 'atom'
374 assert_response :success
375 assert_template 'changes.rxml'
376 # Inline image
377 assert @response.body.include?("&lt;img src=\"http://test.host/attachments/download/10\" alt=\"\" /&gt;")
378 end
379
372 def test_new_routing
380 def test_new_routing
373 assert_routing(
381 assert_routing(
374 {:method => :get, :path => '/projects/1/issues/new'},
382 {:method => :get, :path => '/projects/1/issues/new'},
375 :controller => 'issues', :action => 'new', :project_id => '1'
383 :controller => 'issues', :action => 'new', :project_id => '1'
376 )
384 )
377 assert_recognizes(
385 assert_recognizes(
378 {:controller => 'issues', :action => 'new', :project_id => '1'},
386 {:controller => 'issues', :action => 'new', :project_id => '1'},
379 {:method => :post, :path => '/projects/1/issues'}
387 {:method => :post, :path => '/projects/1/issues'}
380 )
388 )
381 end
389 end
382
390
383 def test_show_export_to_pdf
391 def test_show_export_to_pdf
384 get :show, :id => 3, :format => 'pdf'
392 get :show, :id => 3, :format => 'pdf'
385 assert_response :success
393 assert_response :success
386 assert_equal 'application/pdf', @response.content_type
394 assert_equal 'application/pdf', @response.content_type
387 assert @response.body.starts_with?('%PDF')
395 assert @response.body.starts_with?('%PDF')
388 assert_not_nil assigns(:issue)
396 assert_not_nil assigns(:issue)
389 end
397 end
390
398
391 def test_get_new
399 def test_get_new
392 @request.session[:user_id] = 2
400 @request.session[:user_id] = 2
393 get :new, :project_id => 1, :tracker_id => 1
401 get :new, :project_id => 1, :tracker_id => 1
394 assert_response :success
402 assert_response :success
395 assert_template 'new'
403 assert_template 'new'
396
404
397 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
405 assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
398 :value => 'Default string' }
406 :value => 'Default string' }
399 end
407 end
400
408
401 def test_get_new_without_tracker_id
409 def test_get_new_without_tracker_id
402 @request.session[:user_id] = 2
410 @request.session[:user_id] = 2
403 get :new, :project_id => 1
411 get :new, :project_id => 1
404 assert_response :success
412 assert_response :success
405 assert_template 'new'
413 assert_template 'new'
406
414
407 issue = assigns(:issue)
415 issue = assigns(:issue)
408 assert_not_nil issue
416 assert_not_nil issue
409 assert_equal Project.find(1).trackers.first, issue.tracker
417 assert_equal Project.find(1).trackers.first, issue.tracker
410 end
418 end
411
419
412 def test_get_new_with_no_default_status_should_display_an_error
420 def test_get_new_with_no_default_status_should_display_an_error
413 @request.session[:user_id] = 2
421 @request.session[:user_id] = 2
414 IssueStatus.delete_all
422 IssueStatus.delete_all
415
423
416 get :new, :project_id => 1
424 get :new, :project_id => 1
417 assert_response 500
425 assert_response 500
418 assert_not_nil flash[:error]
426 assert_not_nil flash[:error]
419 assert_tag :tag => 'div', :attributes => { :class => /error/ },
427 assert_tag :tag => 'div', :attributes => { :class => /error/ },
420 :content => /No default issue/
428 :content => /No default issue/
421 end
429 end
422
430
423 def test_get_new_with_no_tracker_should_display_an_error
431 def test_get_new_with_no_tracker_should_display_an_error
424 @request.session[:user_id] = 2
432 @request.session[:user_id] = 2
425 Tracker.delete_all
433 Tracker.delete_all
426
434
427 get :new, :project_id => 1
435 get :new, :project_id => 1
428 assert_response 500
436 assert_response 500
429 assert_not_nil flash[:error]
437 assert_not_nil flash[:error]
430 assert_tag :tag => 'div', :attributes => { :class => /error/ },
438 assert_tag :tag => 'div', :attributes => { :class => /error/ },
431 :content => /No tracker/
439 :content => /No tracker/
432 end
440 end
433
441
434 def test_update_new_form
442 def test_update_new_form
435 @request.session[:user_id] = 2
443 @request.session[:user_id] = 2
436 xhr :post, :new, :project_id => 1,
444 xhr :post, :new, :project_id => 1,
437 :issue => {:tracker_id => 2,
445 :issue => {:tracker_id => 2,
438 :subject => 'This is the test_new issue',
446 :subject => 'This is the test_new issue',
439 :description => 'This is the description',
447 :description => 'This is the description',
440 :priority_id => 5}
448 :priority_id => 5}
441 assert_response :success
449 assert_response :success
442 assert_template 'new'
450 assert_template 'new'
443 end
451 end
444
452
445 def test_post_new
453 def test_post_new
446 @request.session[:user_id] = 2
454 @request.session[:user_id] = 2
447 post :new, :project_id => 1,
455 post :new, :project_id => 1,
448 :issue => {:tracker_id => 3,
456 :issue => {:tracker_id => 3,
449 :subject => 'This is the test_new issue',
457 :subject => 'This is the test_new issue',
450 :description => 'This is the description',
458 :description => 'This is the description',
451 :priority_id => 5,
459 :priority_id => 5,
452 :estimated_hours => '',
460 :estimated_hours => '',
453 :custom_field_values => {'2' => 'Value for field 2'}}
461 :custom_field_values => {'2' => 'Value for field 2'}}
454 assert_redirected_to :action => 'show'
462 assert_redirected_to :action => 'show'
455
463
456 issue = Issue.find_by_subject('This is the test_new issue')
464 issue = Issue.find_by_subject('This is the test_new issue')
457 assert_not_nil issue
465 assert_not_nil issue
458 assert_equal 2, issue.author_id
466 assert_equal 2, issue.author_id
459 assert_equal 3, issue.tracker_id
467 assert_equal 3, issue.tracker_id
460 assert_nil issue.estimated_hours
468 assert_nil issue.estimated_hours
461 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
469 v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
462 assert_not_nil v
470 assert_not_nil v
463 assert_equal 'Value for field 2', v.value
471 assert_equal 'Value for field 2', v.value
464 end
472 end
465
473
466 def test_post_new_and_continue
474 def test_post_new_and_continue
467 @request.session[:user_id] = 2
475 @request.session[:user_id] = 2
468 post :new, :project_id => 1,
476 post :new, :project_id => 1,
469 :issue => {:tracker_id => 3,
477 :issue => {:tracker_id => 3,
470 :subject => 'This is first issue',
478 :subject => 'This is first issue',
471 :priority_id => 5},
479 :priority_id => 5},
472 :continue => ''
480 :continue => ''
473 assert_redirected_to :controller => 'issues', :action => 'new', :tracker_id => 3
481 assert_redirected_to :controller => 'issues', :action => 'new', :tracker_id => 3
474 end
482 end
475
483
476 def test_post_new_without_custom_fields_param
484 def test_post_new_without_custom_fields_param
477 @request.session[:user_id] = 2
485 @request.session[:user_id] = 2
478 post :new, :project_id => 1,
486 post :new, :project_id => 1,
479 :issue => {:tracker_id => 1,
487 :issue => {:tracker_id => 1,
480 :subject => 'This is the test_new issue',
488 :subject => 'This is the test_new issue',
481 :description => 'This is the description',
489 :description => 'This is the description',
482 :priority_id => 5}
490 :priority_id => 5}
483 assert_redirected_to :action => 'show'
491 assert_redirected_to :action => 'show'
484 end
492 end
485
493
486 def test_post_new_with_required_custom_field_and_without_custom_fields_param
494 def test_post_new_with_required_custom_field_and_without_custom_fields_param
487 field = IssueCustomField.find_by_name('Database')
495 field = IssueCustomField.find_by_name('Database')
488 field.update_attribute(:is_required, true)
496 field.update_attribute(:is_required, true)
489
497
490 @request.session[:user_id] = 2
498 @request.session[:user_id] = 2
491 post :new, :project_id => 1,
499 post :new, :project_id => 1,
492 :issue => {:tracker_id => 1,
500 :issue => {:tracker_id => 1,
493 :subject => 'This is the test_new issue',
501 :subject => 'This is the test_new issue',
494 :description => 'This is the description',
502 :description => 'This is the description',
495 :priority_id => 5}
503 :priority_id => 5}
496 assert_response :success
504 assert_response :success
497 assert_template 'new'
505 assert_template 'new'
498 issue = assigns(:issue)
506 issue = assigns(:issue)
499 assert_not_nil issue
507 assert_not_nil issue
500 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
508 assert_equal I18n.translate('activerecord.errors.messages.invalid'), issue.errors.on(:custom_values)
501 end
509 end
502
510
503 def test_post_new_with_watchers
511 def test_post_new_with_watchers
504 @request.session[:user_id] = 2
512 @request.session[:user_id] = 2
505 ActionMailer::Base.deliveries.clear
513 ActionMailer::Base.deliveries.clear
506
514
507 assert_difference 'Watcher.count', 2 do
515 assert_difference 'Watcher.count', 2 do
508 post :new, :project_id => 1,
516 post :new, :project_id => 1,
509 :issue => {:tracker_id => 1,
517 :issue => {:tracker_id => 1,
510 :subject => 'This is a new issue with watchers',
518 :subject => 'This is a new issue with watchers',
511 :description => 'This is the description',
519 :description => 'This is the description',
512 :priority_id => 5,
520 :priority_id => 5,
513 :watcher_user_ids => ['2', '3']}
521 :watcher_user_ids => ['2', '3']}
514 end
522 end
515 issue = Issue.find_by_subject('This is a new issue with watchers')
523 issue = Issue.find_by_subject('This is a new issue with watchers')
516 assert_not_nil issue
524 assert_not_nil issue
517 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
525 assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
518
526
519 # Watchers added
527 # Watchers added
520 assert_equal [2, 3], issue.watcher_user_ids.sort
528 assert_equal [2, 3], issue.watcher_user_ids.sort
521 assert issue.watched_by?(User.find(3))
529 assert issue.watched_by?(User.find(3))
522 # Watchers notified
530 # Watchers notified
523 mail = ActionMailer::Base.deliveries.last
531 mail = ActionMailer::Base.deliveries.last
524 assert_kind_of TMail::Mail, mail
532 assert_kind_of TMail::Mail, mail
525 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
533 assert [mail.bcc, mail.cc].flatten.include?(User.find(3).mail)
526 end
534 end
527
535
528 def test_post_new_should_send_a_notification
536 def test_post_new_should_send_a_notification
529 ActionMailer::Base.deliveries.clear
537 ActionMailer::Base.deliveries.clear
530 @request.session[:user_id] = 2
538 @request.session[:user_id] = 2
531 post :new, :project_id => 1,
539 post :new, :project_id => 1,
532 :issue => {:tracker_id => 3,
540 :issue => {:tracker_id => 3,
533 :subject => 'This is the test_new issue',
541 :subject => 'This is the test_new issue',
534 :description => 'This is the description',
542 :description => 'This is the description',
535 :priority_id => 5,
543 :priority_id => 5,
536 :estimated_hours => '',
544 :estimated_hours => '',
537 :custom_field_values => {'2' => 'Value for field 2'}}
545 :custom_field_values => {'2' => 'Value for field 2'}}
538 assert_redirected_to :action => 'show'
546 assert_redirected_to :action => 'show'
539
547
540 assert_equal 1, ActionMailer::Base.deliveries.size
548 assert_equal 1, ActionMailer::Base.deliveries.size
541 end
549 end
542
550
543 def test_post_should_preserve_fields_values_on_validation_failure
551 def test_post_should_preserve_fields_values_on_validation_failure
544 @request.session[:user_id] = 2
552 @request.session[:user_id] = 2
545 post :new, :project_id => 1,
553 post :new, :project_id => 1,
546 :issue => {:tracker_id => 1,
554 :issue => {:tracker_id => 1,
547 # empty subject
555 # empty subject
548 :subject => '',
556 :subject => '',
549 :description => 'This is a description',
557 :description => 'This is a description',
550 :priority_id => 6,
558 :priority_id => 6,
551 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
559 :custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
552 assert_response :success
560 assert_response :success
553 assert_template 'new'
561 assert_template 'new'
554
562
555 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
563 assert_tag :textarea, :attributes => { :name => 'issue[description]' },
556 :content => 'This is a description'
564 :content => 'This is a description'
557 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
565 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
558 :child => { :tag => 'option', :attributes => { :selected => 'selected',
566 :child => { :tag => 'option', :attributes => { :selected => 'selected',
559 :value => '6' },
567 :value => '6' },
560 :content => 'High' }
568 :content => 'High' }
561 # Custom fields
569 # Custom fields
562 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
570 assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
563 :child => { :tag => 'option', :attributes => { :selected => 'selected',
571 :child => { :tag => 'option', :attributes => { :selected => 'selected',
564 :value => 'Oracle' },
572 :value => 'Oracle' },
565 :content => 'Oracle' }
573 :content => 'Oracle' }
566 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
574 assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
567 :value => 'Value for field 2'}
575 :value => 'Value for field 2'}
568 end
576 end
569
577
570 def test_copy_routing
578 def test_copy_routing
571 assert_routing(
579 assert_routing(
572 {:method => :get, :path => '/projects/world_domination/issues/567/copy'},
580 {:method => :get, :path => '/projects/world_domination/issues/567/copy'},
573 :controller => 'issues', :action => 'new', :project_id => 'world_domination', :copy_from => '567'
581 :controller => 'issues', :action => 'new', :project_id => 'world_domination', :copy_from => '567'
574 )
582 )
575 end
583 end
576
584
577 def test_copy_issue
585 def test_copy_issue
578 @request.session[:user_id] = 2
586 @request.session[:user_id] = 2
579 get :new, :project_id => 1, :copy_from => 1
587 get :new, :project_id => 1, :copy_from => 1
580 assert_template 'new'
588 assert_template 'new'
581 assert_not_nil assigns(:issue)
589 assert_not_nil assigns(:issue)
582 orig = Issue.find(1)
590 orig = Issue.find(1)
583 assert_equal orig.subject, assigns(:issue).subject
591 assert_equal orig.subject, assigns(:issue).subject
584 end
592 end
585
593
586 def test_edit_routing
594 def test_edit_routing
587 assert_routing(
595 assert_routing(
588 {:method => :get, :path => '/issues/1/edit'},
596 {:method => :get, :path => '/issues/1/edit'},
589 :controller => 'issues', :action => 'edit', :id => '1'
597 :controller => 'issues', :action => 'edit', :id => '1'
590 )
598 )
591 assert_recognizes( #TODO: use a PUT on the issue URI isntead, need to adjust form
599 assert_recognizes( #TODO: use a PUT on the issue URI isntead, need to adjust form
592 {:controller => 'issues', :action => 'edit', :id => '1'},
600 {:controller => 'issues', :action => 'edit', :id => '1'},
593 {:method => :post, :path => '/issues/1/edit'}
601 {:method => :post, :path => '/issues/1/edit'}
594 )
602 )
595 end
603 end
596
604
597 def test_get_edit
605 def test_get_edit
598 @request.session[:user_id] = 2
606 @request.session[:user_id] = 2
599 get :edit, :id => 1
607 get :edit, :id => 1
600 assert_response :success
608 assert_response :success
601 assert_template 'edit'
609 assert_template 'edit'
602 assert_not_nil assigns(:issue)
610 assert_not_nil assigns(:issue)
603 assert_equal Issue.find(1), assigns(:issue)
611 assert_equal Issue.find(1), assigns(:issue)
604 end
612 end
605
613
606 def test_get_edit_with_params
614 def test_get_edit_with_params
607 @request.session[:user_id] = 2
615 @request.session[:user_id] = 2
608 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }
616 get :edit, :id => 1, :issue => { :status_id => 5, :priority_id => 7 }
609 assert_response :success
617 assert_response :success
610 assert_template 'edit'
618 assert_template 'edit'
611
619
612 issue = assigns(:issue)
620 issue = assigns(:issue)
613 assert_not_nil issue
621 assert_not_nil issue
614
622
615 assert_equal 5, issue.status_id
623 assert_equal 5, issue.status_id
616 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
624 assert_tag :select, :attributes => { :name => 'issue[status_id]' },
617 :child => { :tag => 'option',
625 :child => { :tag => 'option',
618 :content => 'Closed',
626 :content => 'Closed',
619 :attributes => { :selected => 'selected' } }
627 :attributes => { :selected => 'selected' } }
620
628
621 assert_equal 7, issue.priority_id
629 assert_equal 7, issue.priority_id
622 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
630 assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
623 :child => { :tag => 'option',
631 :child => { :tag => 'option',
624 :content => 'Urgent',
632 :content => 'Urgent',
625 :attributes => { :selected => 'selected' } }
633 :attributes => { :selected => 'selected' } }
626 end
634 end
627
635
628 def test_reply_routing
636 def test_reply_routing
629 assert_routing(
637 assert_routing(
630 {:method => :post, :path => '/issues/1/quoted'},
638 {:method => :post, :path => '/issues/1/quoted'},
631 :controller => 'issues', :action => 'reply', :id => '1'
639 :controller => 'issues', :action => 'reply', :id => '1'
632 )
640 )
633 end
641 end
634
642
635 def test_reply_to_issue
643 def test_reply_to_issue
636 @request.session[:user_id] = 2
644 @request.session[:user_id] = 2
637 get :reply, :id => 1
645 get :reply, :id => 1
638 assert_response :success
646 assert_response :success
639 assert_select_rjs :show, "update"
647 assert_select_rjs :show, "update"
640 end
648 end
641
649
642 def test_reply_to_note
650 def test_reply_to_note
643 @request.session[:user_id] = 2
651 @request.session[:user_id] = 2
644 get :reply, :id => 1, :journal_id => 2
652 get :reply, :id => 1, :journal_id => 2
645 assert_response :success
653 assert_response :success
646 assert_select_rjs :show, "update"
654 assert_select_rjs :show, "update"
647 end
655 end
648
656
649 def test_post_edit_without_custom_fields_param
657 def test_post_edit_without_custom_fields_param
650 @request.session[:user_id] = 2
658 @request.session[:user_id] = 2
651 ActionMailer::Base.deliveries.clear
659 ActionMailer::Base.deliveries.clear
652
660
653 issue = Issue.find(1)
661 issue = Issue.find(1)
654 assert_equal '125', issue.custom_value_for(2).value
662 assert_equal '125', issue.custom_value_for(2).value
655 old_subject = issue.subject
663 old_subject = issue.subject
656 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
664 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
657
665
658 assert_difference('Journal.count') do
666 assert_difference('Journal.count') do
659 assert_difference('JournalDetail.count', 2) do
667 assert_difference('JournalDetail.count', 2) do
660 post :edit, :id => 1, :issue => {:subject => new_subject,
668 post :edit, :id => 1, :issue => {:subject => new_subject,
661 :priority_id => '6',
669 :priority_id => '6',
662 :category_id => '1' # no change
670 :category_id => '1' # no change
663 }
671 }
664 end
672 end
665 end
673 end
666 assert_redirected_to :action => 'show', :id => '1'
674 assert_redirected_to :action => 'show', :id => '1'
667 issue.reload
675 issue.reload
668 assert_equal new_subject, issue.subject
676 assert_equal new_subject, issue.subject
669 # Make sure custom fields were not cleared
677 # Make sure custom fields were not cleared
670 assert_equal '125', issue.custom_value_for(2).value
678 assert_equal '125', issue.custom_value_for(2).value
671
679
672 mail = ActionMailer::Base.deliveries.last
680 mail = ActionMailer::Base.deliveries.last
673 assert_kind_of TMail::Mail, mail
681 assert_kind_of TMail::Mail, mail
674 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
682 assert mail.subject.starts_with?("[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}]")
675 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
683 assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
676 end
684 end
677
685
678 def test_post_edit_with_custom_field_change
686 def test_post_edit_with_custom_field_change
679 @request.session[:user_id] = 2
687 @request.session[:user_id] = 2
680 issue = Issue.find(1)
688 issue = Issue.find(1)
681 assert_equal '125', issue.custom_value_for(2).value
689 assert_equal '125', issue.custom_value_for(2).value
682
690
683 assert_difference('Journal.count') do
691 assert_difference('Journal.count') do
684 assert_difference('JournalDetail.count', 3) do
692 assert_difference('JournalDetail.count', 3) do
685 post :edit, :id => 1, :issue => {:subject => 'Custom field change',
693 post :edit, :id => 1, :issue => {:subject => 'Custom field change',
686 :priority_id => '6',
694 :priority_id => '6',
687 :category_id => '1', # no change
695 :category_id => '1', # no change
688 :custom_field_values => { '2' => 'New custom value' }
696 :custom_field_values => { '2' => 'New custom value' }
689 }
697 }
690 end
698 end
691 end
699 end
692 assert_redirected_to :action => 'show', :id => '1'
700 assert_redirected_to :action => 'show', :id => '1'
693 issue.reload
701 issue.reload
694 assert_equal 'New custom value', issue.custom_value_for(2).value
702 assert_equal 'New custom value', issue.custom_value_for(2).value
695
703
696 mail = ActionMailer::Base.deliveries.last
704 mail = ActionMailer::Base.deliveries.last
697 assert_kind_of TMail::Mail, mail
705 assert_kind_of TMail::Mail, mail
698 assert mail.body.include?("Searchable field changed from 125 to New custom value")
706 assert mail.body.include?("Searchable field changed from 125 to New custom value")
699 end
707 end
700
708
701 def test_post_edit_with_status_and_assignee_change
709 def test_post_edit_with_status_and_assignee_change
702 issue = Issue.find(1)
710 issue = Issue.find(1)
703 assert_equal 1, issue.status_id
711 assert_equal 1, issue.status_id
704 @request.session[:user_id] = 2
712 @request.session[:user_id] = 2
705 assert_difference('TimeEntry.count', 0) do
713 assert_difference('TimeEntry.count', 0) do
706 post :edit,
714 post :edit,
707 :id => 1,
715 :id => 1,
708 :issue => { :status_id => 2, :assigned_to_id => 3 },
716 :issue => { :status_id => 2, :assigned_to_id => 3 },
709 :notes => 'Assigned to dlopper',
717 :notes => 'Assigned to dlopper',
710 :time_entry => { :hours => '', :comments => '', :activity_id => Enumeration.activities.first }
718 :time_entry => { :hours => '', :comments => '', :activity_id => Enumeration.activities.first }
711 end
719 end
712 assert_redirected_to :action => 'show', :id => '1'
720 assert_redirected_to :action => 'show', :id => '1'
713 issue.reload
721 issue.reload
714 assert_equal 2, issue.status_id
722 assert_equal 2, issue.status_id
715 j = issue.journals.find(:first, :order => 'id DESC')
723 j = issue.journals.find(:first, :order => 'id DESC')
716 assert_equal 'Assigned to dlopper', j.notes
724 assert_equal 'Assigned to dlopper', j.notes
717 assert_equal 2, j.details.size
725 assert_equal 2, j.details.size
718
726
719 mail = ActionMailer::Base.deliveries.last
727 mail = ActionMailer::Base.deliveries.last
720 assert mail.body.include?("Status changed from New to Assigned")
728 assert mail.body.include?("Status changed from New to Assigned")
721 # subject should contain the new status
729 # subject should contain the new status
722 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
730 assert mail.subject.include?("(#{ IssueStatus.find(2).name })")
723 end
731 end
724
732
725 def test_post_edit_with_note_only
733 def test_post_edit_with_note_only
726 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
734 notes = 'Note added by IssuesControllerTest#test_update_with_note_only'
727 # anonymous user
735 # anonymous user
728 post :edit,
736 post :edit,
729 :id => 1,
737 :id => 1,
730 :notes => notes
738 :notes => notes
731 assert_redirected_to :action => 'show', :id => '1'
739 assert_redirected_to :action => 'show', :id => '1'
732 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
740 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
733 assert_equal notes, j.notes
741 assert_equal notes, j.notes
734 assert_equal 0, j.details.size
742 assert_equal 0, j.details.size
735 assert_equal User.anonymous, j.user
743 assert_equal User.anonymous, j.user
736
744
737 mail = ActionMailer::Base.deliveries.last
745 mail = ActionMailer::Base.deliveries.last
738 assert mail.body.include?(notes)
746 assert mail.body.include?(notes)
739 end
747 end
740
748
741 def test_post_edit_with_note_and_spent_time
749 def test_post_edit_with_note_and_spent_time
742 @request.session[:user_id] = 2
750 @request.session[:user_id] = 2
743 spent_hours_before = Issue.find(1).spent_hours
751 spent_hours_before = Issue.find(1).spent_hours
744 assert_difference('TimeEntry.count') do
752 assert_difference('TimeEntry.count') do
745 post :edit,
753 post :edit,
746 :id => 1,
754 :id => 1,
747 :notes => '2.5 hours added',
755 :notes => '2.5 hours added',
748 :time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.activities.first }
756 :time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.activities.first }
749 end
757 end
750 assert_redirected_to :action => 'show', :id => '1'
758 assert_redirected_to :action => 'show', :id => '1'
751
759
752 issue = Issue.find(1)
760 issue = Issue.find(1)
753
761
754 j = issue.journals.find(:first, :order => 'id DESC')
762 j = issue.journals.find(:first, :order => 'id DESC')
755 assert_equal '2.5 hours added', j.notes
763 assert_equal '2.5 hours added', j.notes
756 assert_equal 0, j.details.size
764 assert_equal 0, j.details.size
757
765
758 t = issue.time_entries.find(:first, :order => 'id DESC')
766 t = issue.time_entries.find(:first, :order => 'id DESC')
759 assert_not_nil t
767 assert_not_nil t
760 assert_equal 2.5, t.hours
768 assert_equal 2.5, t.hours
761 assert_equal spent_hours_before + 2.5, issue.spent_hours
769 assert_equal spent_hours_before + 2.5, issue.spent_hours
762 end
770 end
763
771
764 def test_post_edit_with_attachment_only
772 def test_post_edit_with_attachment_only
765 set_tmp_attachments_directory
773 set_tmp_attachments_directory
766
774
767 # Delete all fixtured journals, a race condition can occur causing the wrong
775 # Delete all fixtured journals, a race condition can occur causing the wrong
768 # journal to get fetched in the next find.
776 # journal to get fetched in the next find.
769 Journal.delete_all
777 Journal.delete_all
770
778
771 # anonymous user
779 # anonymous user
772 post :edit,
780 post :edit,
773 :id => 1,
781 :id => 1,
774 :notes => '',
782 :notes => '',
775 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
783 :attachments => {'1' => {'file' => test_uploaded_file('testfile.txt', 'text/plain')}}
776 assert_redirected_to :action => 'show', :id => '1'
784 assert_redirected_to :action => 'show', :id => '1'
777 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
785 j = Issue.find(1).journals.find(:first, :order => 'id DESC')
778 assert j.notes.blank?
786 assert j.notes.blank?
779 assert_equal 1, j.details.size
787 assert_equal 1, j.details.size
780 assert_equal 'testfile.txt', j.details.first.value
788 assert_equal 'testfile.txt', j.details.first.value
781 assert_equal User.anonymous, j.user
789 assert_equal User.anonymous, j.user
782
790
783 mail = ActionMailer::Base.deliveries.last
791 mail = ActionMailer::Base.deliveries.last
784 assert mail.body.include?('testfile.txt')
792 assert mail.body.include?('testfile.txt')
785 end
793 end
786
794
787 def test_post_edit_with_no_change
795 def test_post_edit_with_no_change
788 issue = Issue.find(1)
796 issue = Issue.find(1)
789 issue.journals.clear
797 issue.journals.clear
790 ActionMailer::Base.deliveries.clear
798 ActionMailer::Base.deliveries.clear
791
799
792 post :edit,
800 post :edit,
793 :id => 1,
801 :id => 1,
794 :notes => ''
802 :notes => ''
795 assert_redirected_to :action => 'show', :id => '1'
803 assert_redirected_to :action => 'show', :id => '1'
796
804
797 issue.reload
805 issue.reload
798 assert issue.journals.empty?
806 assert issue.journals.empty?
799 # No email should be sent
807 # No email should be sent
800 assert ActionMailer::Base.deliveries.empty?
808 assert ActionMailer::Base.deliveries.empty?
801 end
809 end
802
810
803 def test_post_edit_should_send_a_notification
811 def test_post_edit_should_send_a_notification
804 @request.session[:user_id] = 2
812 @request.session[:user_id] = 2
805 ActionMailer::Base.deliveries.clear
813 ActionMailer::Base.deliveries.clear
806 issue = Issue.find(1)
814 issue = Issue.find(1)
807 old_subject = issue.subject
815 old_subject = issue.subject
808 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
816 new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
809
817
810 post :edit, :id => 1, :issue => {:subject => new_subject,
818 post :edit, :id => 1, :issue => {:subject => new_subject,
811 :priority_id => '6',
819 :priority_id => '6',
812 :category_id => '1' # no change
820 :category_id => '1' # no change
813 }
821 }
814 assert_equal 1, ActionMailer::Base.deliveries.size
822 assert_equal 1, ActionMailer::Base.deliveries.size
815 end
823 end
816
824
817 def test_post_edit_with_invalid_spent_time
825 def test_post_edit_with_invalid_spent_time
818 @request.session[:user_id] = 2
826 @request.session[:user_id] = 2
819 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
827 notes = 'Note added by IssuesControllerTest#test_post_edit_with_invalid_spent_time'
820
828
821 assert_no_difference('Journal.count') do
829 assert_no_difference('Journal.count') do
822 post :edit,
830 post :edit,
823 :id => 1,
831 :id => 1,
824 :notes => notes,
832 :notes => notes,
825 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
833 :time_entry => {"comments"=>"", "activity_id"=>"", "hours"=>"2z"}
826 end
834 end
827 assert_response :success
835 assert_response :success
828 assert_template 'edit'
836 assert_template 'edit'
829
837
830 assert_tag :textarea, :attributes => { :name => 'notes' },
838 assert_tag :textarea, :attributes => { :name => 'notes' },
831 :content => notes
839 :content => notes
832 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
840 assert_tag :input, :attributes => { :name => 'time_entry[hours]', :value => "2z" }
833 end
841 end
834
842
835 def test_get_bulk_edit
843 def test_get_bulk_edit
836 @request.session[:user_id] = 2
844 @request.session[:user_id] = 2
837 get :bulk_edit, :ids => [1, 2]
845 get :bulk_edit, :ids => [1, 2]
838 assert_response :success
846 assert_response :success
839 assert_template 'bulk_edit'
847 assert_template 'bulk_edit'
840 end
848 end
841
849
842 def test_bulk_edit
850 def test_bulk_edit
843 @request.session[:user_id] = 2
851 @request.session[:user_id] = 2
844 # update issues priority
852 # update issues priority
845 post :bulk_edit, :ids => [1, 2], :priority_id => 7,
853 post :bulk_edit, :ids => [1, 2], :priority_id => 7,
846 :assigned_to_id => '',
854 :assigned_to_id => '',
847 :custom_field_values => {'2' => ''},
855 :custom_field_values => {'2' => ''},
848 :notes => 'Bulk editing'
856 :notes => 'Bulk editing'
849 assert_response 302
857 assert_response 302
850 # check that the issues were updated
858 # check that the issues were updated
851 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
859 assert_equal [7, 7], Issue.find_all_by_id([1, 2]).collect {|i| i.priority.id}
852
860
853 issue = Issue.find(1)
861 issue = Issue.find(1)
854 journal = issue.journals.find(:first, :order => 'created_on DESC')
862 journal = issue.journals.find(:first, :order => 'created_on DESC')
855 assert_equal '125', issue.custom_value_for(2).value
863 assert_equal '125', issue.custom_value_for(2).value
856 assert_equal 'Bulk editing', journal.notes
864 assert_equal 'Bulk editing', journal.notes
857 assert_equal 1, journal.details.size
865 assert_equal 1, journal.details.size
858 end
866 end
859
867
860 def test_bullk_edit_should_send_a_notification
868 def test_bullk_edit_should_send_a_notification
861 @request.session[:user_id] = 2
869 @request.session[:user_id] = 2
862 ActionMailer::Base.deliveries.clear
870 ActionMailer::Base.deliveries.clear
863 post(:bulk_edit,
871 post(:bulk_edit,
864 {
872 {
865 :ids => [1, 2],
873 :ids => [1, 2],
866 :priority_id => 7,
874 :priority_id => 7,
867 :assigned_to_id => '',
875 :assigned_to_id => '',
868 :custom_field_values => {'2' => ''},
876 :custom_field_values => {'2' => ''},
869 :notes => 'Bulk editing'
877 :notes => 'Bulk editing'
870 })
878 })
871
879
872 assert_response 302
880 assert_response 302
873 assert_equal 2, ActionMailer::Base.deliveries.size
881 assert_equal 2, ActionMailer::Base.deliveries.size
874 end
882 end
875
883
876 def test_bulk_edit_status
884 def test_bulk_edit_status
877 @request.session[:user_id] = 2
885 @request.session[:user_id] = 2
878 # update issues priority
886 # update issues priority
879 post :bulk_edit, :ids => [1, 2], :priority_id => '',
887 post :bulk_edit, :ids => [1, 2], :priority_id => '',
880 :assigned_to_id => '',
888 :assigned_to_id => '',
881 :status_id => '5',
889 :status_id => '5',
882 :notes => 'Bulk editing status'
890 :notes => 'Bulk editing status'
883 assert_response 302
891 assert_response 302
884 issue = Issue.find(1)
892 issue = Issue.find(1)
885 assert issue.closed?
893 assert issue.closed?
886 end
894 end
887
895
888 def test_bulk_edit_custom_field
896 def test_bulk_edit_custom_field
889 @request.session[:user_id] = 2
897 @request.session[:user_id] = 2
890 # update issues priority
898 # update issues priority
891 post :bulk_edit, :ids => [1, 2], :priority_id => '',
899 post :bulk_edit, :ids => [1, 2], :priority_id => '',
892 :assigned_to_id => '',
900 :assigned_to_id => '',
893 :custom_field_values => {'2' => '777'},
901 :custom_field_values => {'2' => '777'},
894 :notes => 'Bulk editing custom field'
902 :notes => 'Bulk editing custom field'
895 assert_response 302
903 assert_response 302
896
904
897 issue = Issue.find(1)
905 issue = Issue.find(1)
898 journal = issue.journals.find(:first, :order => 'created_on DESC')
906 journal = issue.journals.find(:first, :order => 'created_on DESC')
899 assert_equal '777', issue.custom_value_for(2).value
907 assert_equal '777', issue.custom_value_for(2).value
900 assert_equal 1, journal.details.size
908 assert_equal 1, journal.details.size
901 assert_equal '125', journal.details.first.old_value
909 assert_equal '125', journal.details.first.old_value
902 assert_equal '777', journal.details.first.value
910 assert_equal '777', journal.details.first.value
903 end
911 end
904
912
905 def test_bulk_unassign
913 def test_bulk_unassign
906 assert_not_nil Issue.find(2).assigned_to
914 assert_not_nil Issue.find(2).assigned_to
907 @request.session[:user_id] = 2
915 @request.session[:user_id] = 2
908 # unassign issues
916 # unassign issues
909 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk unassigning', :assigned_to_id => 'none'
917 post :bulk_edit, :ids => [1, 2], :notes => 'Bulk unassigning', :assigned_to_id => 'none'
910 assert_response 302
918 assert_response 302
911 # check that the issues were updated
919 # check that the issues were updated
912 assert_nil Issue.find(2).assigned_to
920 assert_nil Issue.find(2).assigned_to
913 end
921 end
914
922
915 def test_move_routing
923 def test_move_routing
916 assert_routing(
924 assert_routing(
917 {:method => :get, :path => '/issues/1/move'},
925 {:method => :get, :path => '/issues/1/move'},
918 :controller => 'issues', :action => 'move', :id => '1'
926 :controller => 'issues', :action => 'move', :id => '1'
919 )
927 )
920 assert_recognizes(
928 assert_recognizes(
921 {:controller => 'issues', :action => 'move', :id => '1'},
929 {:controller => 'issues', :action => 'move', :id => '1'},
922 {:method => :post, :path => '/issues/1/move'}
930 {:method => :post, :path => '/issues/1/move'}
923 )
931 )
924 end
932 end
925
933
926 def test_move_one_issue_to_another_project
934 def test_move_one_issue_to_another_project
927 @request.session[:user_id] = 2
935 @request.session[:user_id] = 2
928 post :move, :id => 1, :new_project_id => 2
936 post :move, :id => 1, :new_project_id => 2
929 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
937 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
930 assert_equal 2, Issue.find(1).project_id
938 assert_equal 2, Issue.find(1).project_id
931 end
939 end
932
940
933 def test_bulk_move_to_another_project
941 def test_bulk_move_to_another_project
934 @request.session[:user_id] = 2
942 @request.session[:user_id] = 2
935 post :move, :ids => [1, 2], :new_project_id => 2
943 post :move, :ids => [1, 2], :new_project_id => 2
936 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
944 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
937 # Issues moved to project 2
945 # Issues moved to project 2
938 assert_equal 2, Issue.find(1).project_id
946 assert_equal 2, Issue.find(1).project_id
939 assert_equal 2, Issue.find(2).project_id
947 assert_equal 2, Issue.find(2).project_id
940 # No tracker change
948 # No tracker change
941 assert_equal 1, Issue.find(1).tracker_id
949 assert_equal 1, Issue.find(1).tracker_id
942 assert_equal 2, Issue.find(2).tracker_id
950 assert_equal 2, Issue.find(2).tracker_id
943 end
951 end
944
952
945 def test_bulk_move_to_another_tracker
953 def test_bulk_move_to_another_tracker
946 @request.session[:user_id] = 2
954 @request.session[:user_id] = 2
947 post :move, :ids => [1, 2], :new_tracker_id => 2
955 post :move, :ids => [1, 2], :new_tracker_id => 2
948 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
956 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
949 assert_equal 2, Issue.find(1).tracker_id
957 assert_equal 2, Issue.find(1).tracker_id
950 assert_equal 2, Issue.find(2).tracker_id
958 assert_equal 2, Issue.find(2).tracker_id
951 end
959 end
952
960
953 def test_bulk_copy_to_another_project
961 def test_bulk_copy_to_another_project
954 @request.session[:user_id] = 2
962 @request.session[:user_id] = 2
955 assert_difference 'Issue.count', 2 do
963 assert_difference 'Issue.count', 2 do
956 assert_no_difference 'Project.find(1).issues.count' do
964 assert_no_difference 'Project.find(1).issues.count' do
957 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
965 post :move, :ids => [1, 2], :new_project_id => 2, :copy_options => {:copy => '1'}
958 end
966 end
959 end
967 end
960 assert_redirected_to 'projects/ecookbook/issues'
968 assert_redirected_to 'projects/ecookbook/issues'
961 end
969 end
962
970
963 def test_context_menu_one_issue
971 def test_context_menu_one_issue
964 @request.session[:user_id] = 2
972 @request.session[:user_id] = 2
965 get :context_menu, :ids => [1]
973 get :context_menu, :ids => [1]
966 assert_response :success
974 assert_response :success
967 assert_template 'context_menu'
975 assert_template 'context_menu'
968 assert_tag :tag => 'a', :content => 'Edit',
976 assert_tag :tag => 'a', :content => 'Edit',
969 :attributes => { :href => '/issues/1/edit',
977 :attributes => { :href => '/issues/1/edit',
970 :class => 'icon-edit' }
978 :class => 'icon-edit' }
971 assert_tag :tag => 'a', :content => 'Closed',
979 assert_tag :tag => 'a', :content => 'Closed',
972 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
980 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
973 :class => '' }
981 :class => '' }
974 assert_tag :tag => 'a', :content => 'Immediate',
982 assert_tag :tag => 'a', :content => 'Immediate',
975 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;priority_id=8',
983 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;priority_id=8',
976 :class => '' }
984 :class => '' }
977 assert_tag :tag => 'a', :content => 'Dave Lopper',
985 assert_tag :tag => 'a', :content => 'Dave Lopper',
978 :attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&amp;ids%5B%5D=1',
986 :attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&amp;ids%5B%5D=1',
979 :class => '' }
987 :class => '' }
980 assert_tag :tag => 'a', :content => 'Copy',
988 assert_tag :tag => 'a', :content => 'Copy',
981 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
989 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
982 :class => 'icon-copy' }
990 :class => 'icon-copy' }
983 assert_tag :tag => 'a', :content => 'Move',
991 assert_tag :tag => 'a', :content => 'Move',
984 :attributes => { :href => '/issues/move?ids%5B%5D=1',
992 :attributes => { :href => '/issues/move?ids%5B%5D=1',
985 :class => 'icon-move' }
993 :class => 'icon-move' }
986 assert_tag :tag => 'a', :content => 'Delete',
994 assert_tag :tag => 'a', :content => 'Delete',
987 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
995 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
988 :class => 'icon-del' }
996 :class => 'icon-del' }
989 end
997 end
990
998
991 def test_context_menu_one_issue_by_anonymous
999 def test_context_menu_one_issue_by_anonymous
992 get :context_menu, :ids => [1]
1000 get :context_menu, :ids => [1]
993 assert_response :success
1001 assert_response :success
994 assert_template 'context_menu'
1002 assert_template 'context_menu'
995 assert_tag :tag => 'a', :content => 'Delete',
1003 assert_tag :tag => 'a', :content => 'Delete',
996 :attributes => { :href => '#',
1004 :attributes => { :href => '#',
997 :class => 'icon-del disabled' }
1005 :class => 'icon-del disabled' }
998 end
1006 end
999
1007
1000 def test_context_menu_multiple_issues_of_same_project
1008 def test_context_menu_multiple_issues_of_same_project
1001 @request.session[:user_id] = 2
1009 @request.session[:user_id] = 2
1002 get :context_menu, :ids => [1, 2]
1010 get :context_menu, :ids => [1, 2]
1003 assert_response :success
1011 assert_response :success
1004 assert_template 'context_menu'
1012 assert_template 'context_menu'
1005 assert_tag :tag => 'a', :content => 'Edit',
1013 assert_tag :tag => 'a', :content => 'Edit',
1006 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
1014 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
1007 :class => 'icon-edit' }
1015 :class => 'icon-edit' }
1008 assert_tag :tag => 'a', :content => 'Immediate',
1016 assert_tag :tag => 'a', :content => 'Immediate',
1009 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;priority_id=8',
1017 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;priority_id=8',
1010 :class => '' }
1018 :class => '' }
1011 assert_tag :tag => 'a', :content => 'Dave Lopper',
1019 assert_tag :tag => 'a', :content => 'Dave Lopper',
1012 :attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
1020 :attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
1013 :class => '' }
1021 :class => '' }
1014 assert_tag :tag => 'a', :content => 'Move',
1022 assert_tag :tag => 'a', :content => 'Move',
1015 :attributes => { :href => '/issues/move?ids%5B%5D=1&amp;ids%5B%5D=2',
1023 :attributes => { :href => '/issues/move?ids%5B%5D=1&amp;ids%5B%5D=2',
1016 :class => 'icon-move' }
1024 :class => 'icon-move' }
1017 assert_tag :tag => 'a', :content => 'Delete',
1025 assert_tag :tag => 'a', :content => 'Delete',
1018 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
1026 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
1019 :class => 'icon-del' }
1027 :class => 'icon-del' }
1020 end
1028 end
1021
1029
1022 def test_context_menu_multiple_issues_of_different_project
1030 def test_context_menu_multiple_issues_of_different_project
1023 @request.session[:user_id] = 2
1031 @request.session[:user_id] = 2
1024 get :context_menu, :ids => [1, 2, 4]
1032 get :context_menu, :ids => [1, 2, 4]
1025 assert_response :success
1033 assert_response :success
1026 assert_template 'context_menu'
1034 assert_template 'context_menu'
1027 assert_tag :tag => 'a', :content => 'Delete',
1035 assert_tag :tag => 'a', :content => 'Delete',
1028 :attributes => { :href => '#',
1036 :attributes => { :href => '#',
1029 :class => 'icon-del disabled' }
1037 :class => 'icon-del disabled' }
1030 end
1038 end
1031
1039
1032 def test_destroy_routing
1040 def test_destroy_routing
1033 assert_recognizes( #TODO: use DELETE on issue URI (need to change forms)
1041 assert_recognizes( #TODO: use DELETE on issue URI (need to change forms)
1034 {:controller => 'issues', :action => 'destroy', :id => '1'},
1042 {:controller => 'issues', :action => 'destroy', :id => '1'},
1035 {:method => :post, :path => '/issues/1/destroy'}
1043 {:method => :post, :path => '/issues/1/destroy'}
1036 )
1044 )
1037 end
1045 end
1038
1046
1039 def test_destroy_issue_with_no_time_entries
1047 def test_destroy_issue_with_no_time_entries
1040 assert_nil TimeEntry.find_by_issue_id(2)
1048 assert_nil TimeEntry.find_by_issue_id(2)
1041 @request.session[:user_id] = 2
1049 @request.session[:user_id] = 2
1042 post :destroy, :id => 2
1050 post :destroy, :id => 2
1043 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1051 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1044 assert_nil Issue.find_by_id(2)
1052 assert_nil Issue.find_by_id(2)
1045 end
1053 end
1046
1054
1047 def test_destroy_issues_with_time_entries
1055 def test_destroy_issues_with_time_entries
1048 @request.session[:user_id] = 2
1056 @request.session[:user_id] = 2
1049 post :destroy, :ids => [1, 3]
1057 post :destroy, :ids => [1, 3]
1050 assert_response :success
1058 assert_response :success
1051 assert_template 'destroy'
1059 assert_template 'destroy'
1052 assert_not_nil assigns(:hours)
1060 assert_not_nil assigns(:hours)
1053 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1061 assert Issue.find_by_id(1) && Issue.find_by_id(3)
1054 end
1062 end
1055
1063
1056 def test_destroy_issues_and_destroy_time_entries
1064 def test_destroy_issues_and_destroy_time_entries
1057 @request.session[:user_id] = 2
1065 @request.session[:user_id] = 2
1058 post :destroy, :ids => [1, 3], :todo => 'destroy'
1066 post :destroy, :ids => [1, 3], :todo => 'destroy'
1059 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1067 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1060 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1068 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1061 assert_nil TimeEntry.find_by_id([1, 2])
1069 assert_nil TimeEntry.find_by_id([1, 2])
1062 end
1070 end
1063
1071
1064 def test_destroy_issues_and_assign_time_entries_to_project
1072 def test_destroy_issues_and_assign_time_entries_to_project
1065 @request.session[:user_id] = 2
1073 @request.session[:user_id] = 2
1066 post :destroy, :ids => [1, 3], :todo => 'nullify'
1074 post :destroy, :ids => [1, 3], :todo => 'nullify'
1067 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1075 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1068 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1076 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1069 assert_nil TimeEntry.find(1).issue_id
1077 assert_nil TimeEntry.find(1).issue_id
1070 assert_nil TimeEntry.find(2).issue_id
1078 assert_nil TimeEntry.find(2).issue_id
1071 end
1079 end
1072
1080
1073 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1081 def test_destroy_issues_and_reassign_time_entries_to_another_issue
1074 @request.session[:user_id] = 2
1082 @request.session[:user_id] = 2
1075 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1083 post :destroy, :ids => [1, 3], :todo => 'reassign', :reassign_to_id => 2
1076 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1084 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
1077 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1085 assert !(Issue.find_by_id(1) || Issue.find_by_id(3))
1078 assert_equal 2, TimeEntry.find(1).issue_id
1086 assert_equal 2, TimeEntry.find(1).issue_id
1079 assert_equal 2, TimeEntry.find(2).issue_id
1087 assert_equal 2, TimeEntry.find(2).issue_id
1080 end
1088 end
1081 end
1089 end
General Comments 0
You need to be logged in to leave comments. Login now