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
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
#
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
#
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')
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|
jplang's avatar
jplang committed
126
      assert_select 'a[rel=nofollow][href=?]', "/issues.#{format.downcase}?project_id=ecookbook", :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