issues_test.rb 8.52 KB
Newer Older
1
# Redmine - project management software
jplang's avatar
jplang committed
2
# Copyright (C) 2006-2016  Jean-Philippe Lang
jplang's avatar
jplang committed
3
4
5
6
7
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
8
#
jplang's avatar
jplang committed
9
10
11
12
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
13
#
jplang's avatar
jplang committed
14
15
16
17
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

18
require File.expand_path('../../test_helper', __FILE__)
jplang's avatar
jplang committed
19

20
class IssuesTest < Redmine::IntegrationTest
21
  fixtures :projects,
22
           :users, :email_addresses,
23
24
           :roles,
           :members,
25
           :member_roles,
26
27
           :trackers,
           :projects_trackers,
28
           :enabled_modules,
29
30
31
32
33
           :issue_statuses,
           :issues,
           :enumerations,
           :custom_fields,
           :custom_values,
jplang's avatar
jplang committed
34
35
           :custom_fields_trackers,
           :attachments
jplang's avatar
jplang committed
36
37
38
39

  # create an issue
  def test_add_issue
    log_user('jsmith', 'jsmith')
jplang's avatar
jplang committed
40
41

    get '/projects/ecookbook/issues/new'
jplang's avatar
jplang committed
42
    assert_response :success
43
    assert_template 'issues/new'
44

jplang's avatar
jplang committed
45
    issue = new_record(Issue) do
jplang's avatar
jplang committed
46
47
48
      post '/projects/ecookbook/issues',
                                 :issue => { :tracker_id => "1",
                                             :start_date => "2006-12-26",
49
50
51
52
                                             :priority_id => "4",
                                             :subject => "new test issue",
                                             :category_id => "",
                                             :description => "new issue",
jplang's avatar
jplang committed
53
54
                                             :done_ratio => "0",
                                             :due_date => "",
55
56
                                             :assigned_to_id => "" },
                                 :custom_fields => {'2' => 'Value for field 2'}
jplang's avatar
jplang committed
57
    end
jplang's avatar
jplang committed
58
    # check redirection
59
    assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
jplang's avatar
jplang committed
60
    follow_redirect!
61
    assert_equal issue, assigns(:issue)
jplang's avatar
jplang committed
62

63
    # check issue attributes
jplang's avatar
jplang committed
64
65
66
67
68
    assert_equal 'jsmith', issue.author.login
    assert_equal 1, issue.project.id
    assert_equal 1, issue.status.id
  end

69
70
71
72
  def test_create_issue_by_anonymous_without_permission_should_fail
    Role.anonymous.remove_permission! :add_issues

    assert_no_difference 'Issue.count' do
73
      post '/projects/1/issues', :tracker_id => "1", :issue => {:subject => "new test issue"}
74
75
76
77
78
79
80
81
    end
    assert_response 302
  end

  def test_create_issue_by_anonymous_with_custom_permission_should_succeed
    Role.anonymous.remove_permission! :add_issues
    Member.create!(:project_id => 1, :principal => Group.anonymous, :role_ids => [3])

jplang's avatar
jplang committed
82
    issue = new_record(Issue) do
83
      post '/projects/1/issues', :tracker_id => "1", :issue => {:subject => "new test issue"}
jplang's avatar
jplang committed
84
      assert_response 302
85
86
87
88
    end
    assert_equal User.anonymous, issue.author
  end

jplang's avatar
jplang committed
89
  # add then remove 2 attachments to an issue
90
  def test_issue_attachments
jplang's avatar
jplang committed
91
    log_user('jsmith', 'jsmith')
jplang's avatar
jplang committed
92
    set_tmp_attachments_directory
jplang's avatar
jplang committed
93

jplang's avatar
jplang committed
94
95
96
97
98
99
    attachment = new_record(Attachment) do
      put '/issues/1',
           :notes => 'Some notes',
           :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'This is an attachment'}}
      assert_redirected_to "/issues/1"
    end
100

jplang's avatar
jplang committed
101
    assert_equal Issue.find(1), attachment.container
jplang's avatar
jplang committed
102
    assert_equal 'testfile.txt', attachment.filename
103
    assert_equal 'This is an attachment', attachment.description
jplang's avatar
jplang committed
104
    # verify the size of the attachment stored in db
105
    #assert_equal file_data_1.length, attachment.filesize
jplang's avatar
jplang committed
106
107
    # verify that the attachment was written to disk
    assert File.exist?(attachment.diskfile)
108

jplang's avatar
jplang committed
109
110
111
112
    # remove the attachments
    Issue.find(1).attachments.each(&:destroy)
    assert_equal 0, Issue.find(1).attachments.length
  end
113

jplang's avatar
jplang committed
114
  def test_other_formats_links_on_index
115
    get '/projects/ecookbook/issues'
116

117
    %w(Atom PDF CSV).each do |format|
118
      assert_select 'a[rel=nofollow][href=?]', "/projects/ecookbook/issues.#{format.downcase}", :text => format
119
120
    end
  end
121

jplang's avatar
jplang committed
122
123
  def test_other_formats_links_on_index_without_project_id_in_url
    get '/issues', :project_id => 'ecookbook'
124

125
    %w(Atom PDF CSV).each do |format|
126
      assert_select 'a[rel=nofollow][href=?]', "/projects/ecookbook/issues.#{format.downcase}", :text => format
127
128
    end
  end
129

jplang's avatar
jplang committed
130
  def test_pagination_links_on_index
jplang's avatar
jplang committed
131
132
    with_settings :per_page_options => '2' do
      get '/projects/ecookbook/issues'
133

134
      assert_select 'a[href=?]', '/projects/ecookbook/issues?page=2', :text => '2'
jplang's avatar
jplang committed
135
    end
136
  end
137

138
  def test_pagination_links_should_preserve_query_parameters
jplang's avatar
jplang committed
139
    with_settings :per_page_options => '2' do
140
141
142
      get '/projects/ecookbook/issues?foo=bar'

      assert_select 'a[href=?]', '/projects/ecookbook/issues?foo=bar&page=2', :text => '2'
jplang's avatar
jplang committed
143
    end
144
  end
145

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  def test_pagination_links_should_not_use_params_as_url_options
    with_settings :per_page_options => '2' do
      get '/projects/ecookbook/issues?host=foo'

      assert_select 'a[href=?]', '/projects/ecookbook/issues?host=foo&page=2', :text => '2'
    end
  end

  def test_sort_links_on_index
    get '/projects/ecookbook/issues'

    assert_select 'a[href=?]', '/projects/ecookbook/issues?sort=subject%2Cid%3Adesc', :text => 'Subject'
  end

  def test_sort_links_should_preserve_query_parameters
    get '/projects/ecookbook/issues?foo=bar'

    assert_select 'a[href=?]', '/projects/ecookbook/issues?foo=bar&sort=subject%2Cid%3Adesc', :text => 'Subject'
  end

  def test_sort_links_should_not_use_params_as_url_options
    get '/projects/ecookbook/issues?host=foo'

    assert_select 'a[href=?]', '/projects/ecookbook/issues?host=foo&sort=subject%2Cid%3Adesc', :text => 'Subject'
  end

172
173
174
  def test_issue_with_user_custom_field
    @field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all)
    Role.anonymous.add_permission! :add_issues, :edit_issues
jplang's avatar
jplang committed
175
    users = Project.find(1).users.uniq.sort
176
    tester = users.first
177

178
179
180
    # Issue form
    get '/projects/ecookbook/issues/new'
    assert_response :success
181
182
183
184
    assert_select 'select[name=?]', "issue[custom_field_values][#{@field.id}]" do
      assert_select 'option', users.size + 1 # +1 for blank value
      assert_select 'option[value=?]', tester.id.to_s, :text => tester.name
    end
185

186
    # Create issue
jplang's avatar
jplang committed
187
    issue = new_record(Issue) do
188
      post '/projects/ecookbook/issues',
189
190
191
192
193
194
        :issue => {
          :tracker_id => '1',
          :priority_id => '4',
          :subject => 'Issue with user custom field',
          :custom_field_values => {@field.id.to_s => users.first.id.to_s}
        }
jplang's avatar
jplang committed
195
      assert_response 302
196
    end
197

198
199
    # Issue view
    follow_redirect!
200
201
202
203
    assert_select ".cf_#{@field.id}" do
      assert_select '.label', :text => 'Tester:'
      assert_select '.value', :text => tester.name
    end
204
205
206
207
    assert_select 'select[name=?]', "issue[custom_field_values][#{@field.id}]" do
      assert_select 'option', users.size + 1 # +1 for blank value
      assert_select 'option[value=?][selected=selected]', tester.id.to_s, :text => tester.name
    end
208

209
    new_tester = users[1]
210
211
212
213
214
215
216
217
218
219
220
221
222
    with_settings :default_language => 'en' do
      # Update issue
      assert_difference 'Journal.count' do
        put "/issues/#{issue.id}",
            :notes => 'Updating custom field',
            :issue => {
                :custom_field_values => {@field.id.to_s => new_tester.id.to_s}
              }
        assert_redirected_to "/issues/#{issue.id}"
      end
      # Issue view
      follow_redirect!
      assert_select 'ul.details li', :text => "Tester changed from #{tester} to #{new_tester}"
223
224
    end
  end
225
226
227
228
229
230
231
232
233

  def test_update_using_invalid_http_verbs
    subject = 'Updated by an invalid http verb'

    get '/issues/update/1', {:issue => {:subject => subject}}, credentials('jsmith')
    assert_response 404
    assert_not_equal subject, Issue.find(1).subject

    post '/issues/1', {:issue => {:subject => subject}}, credentials('jsmith')
jplang's avatar
jplang committed
234
    assert_response 404
235
236
237
238
239
240
    assert_not_equal subject, Issue.find(1).subject
  end

  def test_get_watch_should_be_invalid
    assert_no_difference 'Watcher.count' do
      get '/watchers/watch?object_type=issue&object_id=1', {}, credentials('jsmith')
jplang's avatar
jplang committed
241
      assert_response 404
242
243
    end
  end
jplang's avatar
jplang committed
244
end