##// END OF EJS Templates
Merged r14913 (#21419)....
Jean-Philippe Lang -
r14538:0faa7a72ae3b
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 @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
5 xml.link "rel" => "alternate", "href" => home_url
6 xml.id home_url
6 xml.id home_url
7 xml.icon favicon_url
7 xml.icon favicon_url
8 xml.updated((@journals.first ? @journals.first.event_datetime : Time.now).xmlschema)
8 xml.updated((@journals.first ? @journals.first.event_datetime : Time.now).xmlschema)
9 xml.author { xml.name "#{Setting.app_title}" }
9 xml.author { xml.name "#{Setting.app_title}" }
10 @journals.each do |change|
10 @journals.each do |change|
11 issue = change.issue
11 issue = change.issue
12 xml.entry do
12 xml.entry do
13 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
13 xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
14 xml.link "rel" => "alternate", "href" => issue_url(issue)
14 xml.link "rel" => "alternate", "href" => issue_url(issue)
15 xml.id issue_url(issue, :journal_id => change)
15 xml.id issue_url(issue, :journal_id => change)
16 xml.updated change.created_on.xmlschema
16 xml.updated change.created_on.xmlschema
17 xml.author do
17 xml.author do
18 xml.name change.user.name
18 xml.name change.user.name
19 xml.email(change.user.mail) if change.user.is_a?(User) && !change.user.mail.blank? && !change.user.pref.hide_mail
19 xml.email(change.user.mail) if change.user.is_a?(User) && !change.user.mail.blank? && !change.user.pref.hide_mail
20 end
20 end
21 xml.content "type" => "html" do
21 xml.content "type" => "html" do
22 xml.text! '<ul>'
22 xml.text! '<ul>'
23 details_to_strings(change.details, false).each do |string|
23 details_to_strings(change.visible_details, false).each do |string|
24 xml.text! '<li>' + string + '</li>'
24 xml.text! '<li>' + string + '</li>'
25 end
25 end
26 xml.text! '</ul>'
26 xml.text! '</ul>'
27 xml.text! textilizable(change, :notes, :only_path => false) unless change.notes.blank?
27 xml.text! textilizable(change, :notes, :only_path => false) unless change.notes.blank?
28 end
28 end
29 end
29 end
30 end
30 end
31 end
31 end
@@ -1,181 +1,221
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
2 # Copyright (C) 2006-2015 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 JournalsControllerTest < ActionController::TestCase
20 class JournalsControllerTest < ActionController::TestCase
21 fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules,
21 fixtures :projects, :users, :members, :member_roles, :roles, :issues, :journals, :journal_details, :enabled_modules,
22 :trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects
22 :trackers, :issue_statuses, :enumerations, :custom_fields, :custom_values, :custom_fields_projects, :projects_trackers
23
23
24 def setup
24 def setup
25 User.current = nil
25 User.current = nil
26 end
26 end
27
27
28 def test_index
28 def test_index
29 get :index, :project_id => 1
29 get :index, :project_id => 1
30 assert_response :success
30 assert_response :success
31 assert_not_nil assigns(:journals)
31 assert_not_nil assigns(:journals)
32 assert_equal 'application/atom+xml', @response.content_type
32 assert_equal 'application/atom+xml', @response.content_type
33 end
33 end
34
34
35 def test_index_with_invalid_query_id
35 def test_index_with_invalid_query_id
36 get :index, :project_id => 1, :query_id => 999
36 get :index, :project_id => 1, :query_id => 999
37 assert_response 404
37 assert_response 404
38 end
38 end
39
39
40 def test_index_should_return_privates_notes_with_permission_only
40 def test_index_should_return_privates_notes_with_permission_only
41 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
41 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true, :user_id => 1)
42 @request.session[:user_id] = 2
42 @request.session[:user_id] = 2
43
43
44 get :index, :project_id => 1
44 get :index, :project_id => 1
45 assert_response :success
45 assert_response :success
46 assert_include journal, assigns(:journals)
46 assert_include journal, assigns(:journals)
47
47
48 Role.find(1).remove_permission! :view_private_notes
48 Role.find(1).remove_permission! :view_private_notes
49 get :index, :project_id => 1
49 get :index, :project_id => 1
50 assert_response :success
50 assert_response :success
51 assert_not_include journal, assigns(:journals)
51 assert_not_include journal, assigns(:journals)
52 end
52 end
53
53
54 def test_index_should_show_visible_custom_fields_only
55 Issue.destroy_all
56 field_attributes = {:field_format => 'string', :is_for_all => true, :is_filter => true, :trackers => Tracker.all}
57 @fields = []
58 @fields << (@field1 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 1', :visible => true)))
59 @fields << (@field2 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 2', :visible => false, :role_ids => [1, 2])))
60 @fields << (@field3 = IssueCustomField.create!(field_attributes.merge(:name => 'Field 3', :visible => false, :role_ids => [1, 3])))
61 @issue = Issue.generate!(
62 :author_id => 1,
63 :project_id => 1,
64 :tracker_id => 1,
65 :custom_field_values => {@field1.id => 'Value0', @field2.id => 'Value1', @field3.id => 'Value2'}
66 )
67 @issue.init_journal(User.find(1))
68 @issue.update_attribute :custom_field_values, {@field1.id => 'NewValue0', @field2.id => 'NewValue1', @field3.id => 'NewValue2'}
69
70
71 user_with_role_on_other_project = User.generate!
72 User.add_to_project(user_with_role_on_other_project, Project.find(2), Role.find(3))
73 users_to_test = {
74 User.find(1) => [@field1, @field2, @field3],
75 User.find(3) => [@field1, @field2],
76 user_with_role_on_other_project => [@field1], # should see field1 only on Project 1
77 User.generate! => [@field1],
78 User.anonymous => [@field1]
79 }
80
81 users_to_test.each do |user, visible_fields|
82 get :index, :format => 'atom', :key => user.rss_key
83 @fields.each_with_index do |field, i|
84 if visible_fields.include?(field)
85 assert_select "content[type=html]", { :text => /NewValue#{i}/, :count => 1 }, "User #{user.id} was not able to view #{field.name} in API"
86 else
87 assert_select "content[type=html]", { :text => /NewValue#{i}/, :count => 0 }, "User #{user.id} was able to view #{field.name} in API"
88 end
89 end
90 end
91
92 end
93
54 def test_diff_for_description_change
94 def test_diff_for_description_change
55 get :diff, :id => 3, :detail_id => 4
95 get :diff, :id => 3, :detail_id => 4
56 assert_response :success
96 assert_response :success
57 assert_template 'diff'
97 assert_template 'diff'
58
98
59 assert_select 'span.diff_out', :text => /removed/
99 assert_select 'span.diff_out', :text => /removed/
60 assert_select 'span.diff_in', :text => /added/
100 assert_select 'span.diff_in', :text => /added/
61 end
101 end
62
102
63 def test_diff_for_custom_field
103 def test_diff_for_custom_field
64 field = IssueCustomField.create!(:name => "Long field", :field_format => 'text')
104 field = IssueCustomField.create!(:name => "Long field", :field_format => 'text')
65 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Notes', :user_id => 1)
105 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Notes', :user_id => 1)
66 detail = JournalDetail.create!(:journal => journal, :property => 'cf', :prop_key => field.id,
106 detail = JournalDetail.create!(:journal => journal, :property => 'cf', :prop_key => field.id,
67 :old_value => 'Foo', :value => 'Bar')
107 :old_value => 'Foo', :value => 'Bar')
68
108
69 get :diff, :id => journal.id, :detail_id => detail.id
109 get :diff, :id => journal.id, :detail_id => detail.id
70 assert_response :success
110 assert_response :success
71 assert_template 'diff'
111 assert_template 'diff'
72
112
73 assert_select 'span.diff_out', :text => /Foo/
113 assert_select 'span.diff_out', :text => /Foo/
74 assert_select 'span.diff_in', :text => /Bar/
114 assert_select 'span.diff_in', :text => /Bar/
75 end
115 end
76
116
77 def test_diff_for_custom_field_should_be_denied_if_custom_field_is_not_visible
117 def test_diff_for_custom_field_should_be_denied_if_custom_field_is_not_visible
78 field = IssueCustomField.create!(:name => "Long field", :field_format => 'text', :visible => false, :role_ids => [1])
118 field = IssueCustomField.create!(:name => "Long field", :field_format => 'text', :visible => false, :role_ids => [1])
79 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Notes', :user_id => 1)
119 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Notes', :user_id => 1)
80 detail = JournalDetail.create!(:journal => journal, :property => 'cf', :prop_key => field.id,
120 detail = JournalDetail.create!(:journal => journal, :property => 'cf', :prop_key => field.id,
81 :old_value => 'Foo', :value => 'Bar')
121 :old_value => 'Foo', :value => 'Bar')
82
122
83 get :diff, :id => journal.id, :detail_id => detail.id
123 get :diff, :id => journal.id, :detail_id => detail.id
84 assert_response 302
124 assert_response 302
85 end
125 end
86
126
87 def test_diff_should_default_to_description_diff
127 def test_diff_should_default_to_description_diff
88 get :diff, :id => 3
128 get :diff, :id => 3
89 assert_response :success
129 assert_response :success
90 assert_template 'diff'
130 assert_template 'diff'
91
131
92 assert_select 'span.diff_out', :text => /removed/
132 assert_select 'span.diff_out', :text => /removed/
93 assert_select 'span.diff_in', :text => /added/
133 assert_select 'span.diff_in', :text => /added/
94 end
134 end
95
135
96 def test_reply_to_issue
136 def test_reply_to_issue
97 @request.session[:user_id] = 2
137 @request.session[:user_id] = 2
98 xhr :get, :new, :id => 6
138 xhr :get, :new, :id => 6
99 assert_response :success
139 assert_response :success
100 assert_template 'new'
140 assert_template 'new'
101 assert_equal 'text/javascript', response.content_type
141 assert_equal 'text/javascript', response.content_type
102 assert_include '> This is an issue', response.body
142 assert_include '> This is an issue', response.body
103 end
143 end
104
144
105 def test_reply_to_issue_without_permission
145 def test_reply_to_issue_without_permission
106 @request.session[:user_id] = 7
146 @request.session[:user_id] = 7
107 xhr :get, :new, :id => 6
147 xhr :get, :new, :id => 6
108 assert_response 403
148 assert_response 403
109 end
149 end
110
150
111 def test_reply_to_note
151 def test_reply_to_note
112 @request.session[:user_id] = 2
152 @request.session[:user_id] = 2
113 xhr :get, :new, :id => 6, :journal_id => 4
153 xhr :get, :new, :id => 6, :journal_id => 4
114 assert_response :success
154 assert_response :success
115 assert_template 'new'
155 assert_template 'new'
116 assert_equal 'text/javascript', response.content_type
156 assert_equal 'text/javascript', response.content_type
117 assert_include '> A comment with a private version', response.body
157 assert_include '> A comment with a private version', response.body
118 end
158 end
119
159
120 def test_reply_to_private_note_should_fail_without_permission
160 def test_reply_to_private_note_should_fail_without_permission
121 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true)
161 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true)
122 @request.session[:user_id] = 2
162 @request.session[:user_id] = 2
123
163
124 xhr :get, :new, :id => 2, :journal_id => journal.id
164 xhr :get, :new, :id => 2, :journal_id => journal.id
125 assert_response :success
165 assert_response :success
126 assert_template 'new'
166 assert_template 'new'
127 assert_equal 'text/javascript', response.content_type
167 assert_equal 'text/javascript', response.content_type
128 assert_include '> Privates notes', response.body
168 assert_include '> Privates notes', response.body
129
169
130 Role.find(1).remove_permission! :view_private_notes
170 Role.find(1).remove_permission! :view_private_notes
131 xhr :get, :new, :id => 2, :journal_id => journal.id
171 xhr :get, :new, :id => 2, :journal_id => journal.id
132 assert_response 404
172 assert_response 404
133 end
173 end
134
174
135 def test_edit_xhr
175 def test_edit_xhr
136 @request.session[:user_id] = 1
176 @request.session[:user_id] = 1
137 xhr :get, :edit, :id => 2
177 xhr :get, :edit, :id => 2
138 assert_response :success
178 assert_response :success
139 assert_template 'edit'
179 assert_template 'edit'
140 assert_equal 'text/javascript', response.content_type
180 assert_equal 'text/javascript', response.content_type
141 assert_include 'textarea', response.body
181 assert_include 'textarea', response.body
142 end
182 end
143
183
144 def test_edit_private_note_should_fail_without_permission
184 def test_edit_private_note_should_fail_without_permission
145 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true)
185 journal = Journal.create!(:journalized => Issue.find(2), :notes => 'Privates notes', :private_notes => true)
146 @request.session[:user_id] = 2
186 @request.session[:user_id] = 2
147 Role.find(1).add_permission! :edit_issue_notes
187 Role.find(1).add_permission! :edit_issue_notes
148
188
149 xhr :get, :edit, :id => journal.id
189 xhr :get, :edit, :id => journal.id
150 assert_response :success
190 assert_response :success
151 assert_template 'edit'
191 assert_template 'edit'
152 assert_equal 'text/javascript', response.content_type
192 assert_equal 'text/javascript', response.content_type
153 assert_include 'textarea', response.body
193 assert_include 'textarea', response.body
154
194
155 Role.find(1).remove_permission! :view_private_notes
195 Role.find(1).remove_permission! :view_private_notes
156 xhr :get, :edit, :id => journal.id
196 xhr :get, :edit, :id => journal.id
157 assert_response 404
197 assert_response 404
158 end
198 end
159
199
160 def test_update_xhr
200 def test_update_xhr
161 @request.session[:user_id] = 1
201 @request.session[:user_id] = 1
162 xhr :post, :edit, :id => 2, :notes => 'Updated notes'
202 xhr :post, :edit, :id => 2, :notes => 'Updated notes'
163 assert_response :success
203 assert_response :success
164 assert_template 'update'
204 assert_template 'update'
165 assert_equal 'text/javascript', response.content_type
205 assert_equal 'text/javascript', response.content_type
166 assert_equal 'Updated notes', Journal.find(2).notes
206 assert_equal 'Updated notes', Journal.find(2).notes
167 assert_include 'journal-2-notes', response.body
207 assert_include 'journal-2-notes', response.body
168 end
208 end
169
209
170 def test_update_xhr_with_empty_notes_should_delete_the_journal
210 def test_update_xhr_with_empty_notes_should_delete_the_journal
171 @request.session[:user_id] = 1
211 @request.session[:user_id] = 1
172 assert_difference 'Journal.count', -1 do
212 assert_difference 'Journal.count', -1 do
173 xhr :post, :edit, :id => 2, :notes => ''
213 xhr :post, :edit, :id => 2, :notes => ''
174 assert_response :success
214 assert_response :success
175 assert_template 'update'
215 assert_template 'update'
176 assert_equal 'text/javascript', response.content_type
216 assert_equal 'text/javascript', response.content_type
177 end
217 end
178 assert_nil Journal.find_by_id(2)
218 assert_nil Journal.find_by_id(2)
179 assert_include 'change-2', response.body
219 assert_include 'change-2', response.body
180 end
220 end
181 end
221 end
General Comments 0
You need to be logged in to leave comments. Login now