To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / test / functional / projects_controller_test.rb @ 441:cbce1fd3b1b7

History | View | Annotate | Download (18.5 KB)

1 0:513646585e45 Chris
# Redmine - project management software
2 441:cbce1fd3b1b7 Chris
# Copyright (C) 2006-2011  Jean-Philippe Lang
3 0:513646585e45 Chris
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8 441:cbce1fd3b1b7 Chris
#
9 0:513646585e45 Chris
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13 441:cbce1fd3b1b7 Chris
#
14 0:513646585e45 Chris
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17
18 119:8661b858af72 Chris
require File.expand_path('../../test_helper', __FILE__)
19 0:513646585e45 Chris
require 'projects_controller'
20
21
# Re-raise errors caught by the controller.
22
class ProjectsController; def rescue_action(e) raise e end; end
23
24
class ProjectsControllerTest < ActionController::TestCase
25
  fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
26
           :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
27
           :attachments, :custom_fields, :custom_values, :time_entries
28
29
  def setup
30
    @controller = ProjectsController.new
31
    @request    = ActionController::TestRequest.new
32
    @response   = ActionController::TestResponse.new
33
    @request.session[:user_id] = nil
34
    Setting.default_language = 'en'
35
  end
36 441:cbce1fd3b1b7 Chris
37 0:513646585e45 Chris
  def test_index
38
    get :index
39
    assert_response :success
40
    assert_template 'index'
41
    assert_not_nil assigns(:projects)
42 441:cbce1fd3b1b7 Chris
43 0:513646585e45 Chris
    assert_tag :ul, :child => {:tag => 'li',
44
                               :descendant => {:tag => 'a', :content => 'eCookbook'},
45
                               :child => { :tag => 'ul',
46
                                           :descendant => { :tag => 'a',
47
                                                            :content => 'Child of private child'
48
                                                           }
49
                                          }
50
                               }
51 441:cbce1fd3b1b7 Chris
52 0:513646585e45 Chris
    assert_no_tag :a, :content => /Private child of eCookbook/
53
  end
54 441:cbce1fd3b1b7 Chris
55 0:513646585e45 Chris
  def test_index_atom
56
    get :index, :format => 'atom'
57
    assert_response :success
58
    assert_template 'common/feed.atom.rxml'
59
    assert_select 'feed>title', :text => 'Redmine: Latest projects'
60 441:cbce1fd3b1b7 Chris
    assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_condition(User.current))
61 0:513646585e45 Chris
  end
62 441:cbce1fd3b1b7 Chris
63 0:513646585e45 Chris
  context "#index" do
64
    context "by non-admin user with view_time_entries permission" do
65
      setup do
66
        @request.session[:user_id] = 3
67
      end
68
      should "show overall spent time link" do
69
        get :index
70
        assert_template 'index'
71
        assert_tag :a, :attributes => {:href => '/time_entries'}
72
      end
73
    end
74 441:cbce1fd3b1b7 Chris
75 0:513646585e45 Chris
    context "by non-admin user without view_time_entries permission" do
76
      setup do
77
        Role.find(2).remove_permission! :view_time_entries
78
        Role.non_member.remove_permission! :view_time_entries
79
        Role.anonymous.remove_permission! :view_time_entries
80
        @request.session[:user_id] = 3
81
      end
82
      should "not show overall spent time link" do
83
        get :index
84
        assert_template 'index'
85
        assert_no_tag :a, :attributes => {:href => '/time_entries'}
86
      end
87 441:cbce1fd3b1b7 Chris
    end
88 0:513646585e45 Chris
  end
89 441:cbce1fd3b1b7 Chris
90 22:40f7cfd4df19 chris
  context "#new" do
91 0:513646585e45 Chris
    context "by admin user" do
92
      setup do
93
        @request.session[:user_id] = 1
94
      end
95 441:cbce1fd3b1b7 Chris
96 0:513646585e45 Chris
      should "accept get" do
97 22:40f7cfd4df19 chris
        get :new
98 0:513646585e45 Chris
        assert_response :success
99 22:40f7cfd4df19 chris
        assert_template 'new'
100
      end
101
102
    end
103
104
    context "by non-admin user with add_project permission" do
105
      setup do
106
        Role.non_member.add_permission! :add_project
107
        @request.session[:user_id] = 9
108
      end
109
110
      should "accept get" do
111
        get :new
112
        assert_response :success
113
        assert_template 'new'
114
        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'}
115
      end
116
    end
117
118
    context "by non-admin user with add_subprojects permission" do
119
      setup do
120
        Role.find(1).remove_permission! :add_project
121
        Role.find(1).add_permission! :add_subprojects
122
        @request.session[:user_id] = 2
123 0:513646585e45 Chris
      end
124 441:cbce1fd3b1b7 Chris
125 22:40f7cfd4df19 chris
      should "accept get" do
126
        get :new, :parent_id => 'ecookbook'
127
        assert_response :success
128
        assert_template 'new'
129
        # parent project selected
130
        assert_tag :select, :attributes => {:name => 'project[parent_id]'},
131
                            :child => {:tag => 'option', :attributes => {:value => '1', :selected => 'selected'}}
132
        # no empty value
133
        assert_no_tag :select, :attributes => {:name => 'project[parent_id]'},
134
                               :child => {:tag => 'option', :attributes => {:value => ''}}
135
      end
136
    end
137 441:cbce1fd3b1b7 Chris
138 22:40f7cfd4df19 chris
  end
139
140
  context "POST :create" do
141
    context "by admin user" do
142
      setup do
143
        @request.session[:user_id] = 1
144
      end
145 441:cbce1fd3b1b7 Chris
146 22:40f7cfd4df19 chris
      should "create a new project" do
147 119:8661b858af72 Chris
        post :create,
148
          :project => {
149 441:cbce1fd3b1b7 Chris
            :name => "blog",
150 119:8661b858af72 Chris
            :description => "weblog",
151
            :homepage => 'http://weblog',
152
            :identifier => "blog",
153
            :is_public => 1,
154
            :custom_field_values => { '3' => 'Beta' },
155
            :tracker_ids => ['1', '3'],
156
            # an issue custom field that is not for all project
157
            :issue_custom_field_ids => ['9'],
158
            :enabled_module_names => ['issue_tracking', 'news', 'repository']
159
          }
160 0:513646585e45 Chris
        assert_redirected_to '/projects/blog/settings'
161 441:cbce1fd3b1b7 Chris
162 0:513646585e45 Chris
        project = Project.find_by_name('blog')
163
        assert_kind_of Project, project
164 119:8661b858af72 Chris
        assert project.active?
165 441:cbce1fd3b1b7 Chris
        assert_equal 'weblog', project.description
166 119:8661b858af72 Chris
        assert_equal 'http://weblog', project.homepage
167 0:513646585e45 Chris
        assert_equal true, project.is_public?
168
        assert_nil project.parent
169 119:8661b858af72 Chris
        assert_equal 'Beta', project.custom_value_for(3).value
170
        assert_equal [1, 3], project.trackers.map(&:id).sort
171
        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
172
        assert project.issue_custom_fields.include?(IssueCustomField.find(9))
173 0:513646585e45 Chris
      end
174 441:cbce1fd3b1b7 Chris
175 22:40f7cfd4df19 chris
      should "create a new subproject" do
176 441:cbce1fd3b1b7 Chris
        post :create, :project => { :name => "blog",
177 0:513646585e45 Chris
                                 :description => "weblog",
178
                                 :identifier => "blog",
179
                                 :is_public => 1,
180
                                 :custom_field_values => { '3' => 'Beta' },
181
                                 :parent_id => 1
182
                                }
183
        assert_redirected_to '/projects/blog/settings'
184 441:cbce1fd3b1b7 Chris
185 0:513646585e45 Chris
        project = Project.find_by_name('blog')
186
        assert_kind_of Project, project
187
        assert_equal Project.find(1), project.parent
188
      end
189
    end
190 441:cbce1fd3b1b7 Chris
191 0:513646585e45 Chris
    context "by non-admin user with add_project permission" do
192
      setup do
193
        Role.non_member.add_permission! :add_project
194
        @request.session[:user_id] = 9
195
      end
196 441:cbce1fd3b1b7 Chris
197 22:40f7cfd4df19 chris
      should "accept create a Project" do
198 441:cbce1fd3b1b7 Chris
        post :create, :project => { :name => "blog",
199 0:513646585e45 Chris
                                 :description => "weblog",
200
                                 :identifier => "blog",
201
                                 :is_public => 1,
202 119:8661b858af72 Chris
                                 :custom_field_values => { '3' => 'Beta' },
203
                                 :tracker_ids => ['1', '3'],
204
                                 :enabled_module_names => ['issue_tracking', 'news', 'repository']
205 0:513646585e45 Chris
                                }
206 441:cbce1fd3b1b7 Chris
207 0:513646585e45 Chris
        assert_redirected_to '/projects/blog/settings'
208 441:cbce1fd3b1b7 Chris
209 0:513646585e45 Chris
        project = Project.find_by_name('blog')
210
        assert_kind_of Project, project
211 441:cbce1fd3b1b7 Chris
        assert_equal 'weblog', project.description
212 0:513646585e45 Chris
        assert_equal true, project.is_public?
213 119:8661b858af72 Chris
        assert_equal [1, 3], project.trackers.map(&:id).sort
214
        assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
215 441:cbce1fd3b1b7 Chris
216 0:513646585e45 Chris
        # User should be added as a project member
217
        assert User.find(9).member_of?(project)
218
        assert_equal 1, project.members.size
219
      end
220 441:cbce1fd3b1b7 Chris
221 0:513646585e45 Chris
      should "fail with parent_id" do
222
        assert_no_difference 'Project.count' do
223 441:cbce1fd3b1b7 Chris
          post :create, :project => { :name => "blog",
224 0:513646585e45 Chris
                                   :description => "weblog",
225
                                   :identifier => "blog",
226
                                   :is_public => 1,
227
                                   :custom_field_values => { '3' => 'Beta' },
228
                                   :parent_id => 1
229
                                  }
230
        end
231
        assert_response :success
232
        project = assigns(:project)
233
        assert_kind_of Project, project
234
        assert_not_nil project.errors.on(:parent_id)
235
      end
236
    end
237 441:cbce1fd3b1b7 Chris
238 0:513646585e45 Chris
    context "by non-admin user with add_subprojects permission" do
239
      setup do
240
        Role.find(1).remove_permission! :add_project
241
        Role.find(1).add_permission! :add_subprojects
242
        @request.session[:user_id] = 2
243
      end
244 441:cbce1fd3b1b7 Chris
245 22:40f7cfd4df19 chris
      should "create a project with a parent_id" do
246 441:cbce1fd3b1b7 Chris
        post :create, :project => { :name => "blog",
247 0:513646585e45 Chris
                                 :description => "weblog",
248
                                 :identifier => "blog",
249
                                 :is_public => 1,
250
                                 :custom_field_values => { '3' => 'Beta' },
251
                                 :parent_id => 1
252
                                }
253
        assert_redirected_to '/projects/blog/settings'
254
        project = Project.find_by_name('blog')
255
      end
256 441:cbce1fd3b1b7 Chris
257 0:513646585e45 Chris
      should "fail without parent_id" do
258
        assert_no_difference 'Project.count' do
259 441:cbce1fd3b1b7 Chris
          post :create, :project => { :name => "blog",
260 0:513646585e45 Chris
                                   :description => "weblog",
261
                                   :identifier => "blog",
262
                                   :is_public => 1,
263
                                   :custom_field_values => { '3' => 'Beta' }
264
                                  }
265
        end
266
        assert_response :success
267
        project = assigns(:project)
268
        assert_kind_of Project, project
269
        assert_not_nil project.errors.on(:parent_id)
270
      end
271 441:cbce1fd3b1b7 Chris
272 0:513646585e45 Chris
      should "fail with unauthorized parent_id" do
273
        assert !User.find(2).member_of?(Project.find(6))
274
        assert_no_difference 'Project.count' do
275 441:cbce1fd3b1b7 Chris
          post :create, :project => { :name => "blog",
276 0:513646585e45 Chris
                                   :description => "weblog",
277
                                   :identifier => "blog",
278
                                   :is_public => 1,
279
                                   :custom_field_values => { '3' => 'Beta' },
280
                                   :parent_id => 6
281
                                  }
282
        end
283
        assert_response :success
284
        project = assigns(:project)
285
        assert_kind_of Project, project
286
        assert_not_nil project.errors.on(:parent_id)
287
      end
288
    end
289
  end
290 441:cbce1fd3b1b7 Chris
291
  def test_create_should_preserve_modules_on_validation_failure
292
    with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
293
      @request.session[:user_id] = 1
294
      assert_no_difference 'Project.count' do
295
        post :create, :project => {
296
          :name => "blog",
297
          :identifier => "",
298
          :enabled_module_names => %w(issue_tracking news)
299
        }
300
      end
301
      assert_response :success
302
      project = assigns(:project)
303
      assert_equal %w(issue_tracking news), project.enabled_module_names.sort
304
    end
305
  end
306
307 119:8661b858af72 Chris
  def test_create_should_not_accept_get
308
    @request.session[:user_id] = 1
309
    get :create
310
    assert_response :method_not_allowed
311
  end
312 441:cbce1fd3b1b7 Chris
313 0:513646585e45 Chris
  def test_show_by_id
314
    get :show, :id => 1
315
    assert_response :success
316
    assert_template 'show'
317
    assert_not_nil assigns(:project)
318
  end
319
320
  def test_show_by_identifier
321
    get :show, :id => 'ecookbook'
322
    assert_response :success
323
    assert_template 'show'
324
    assert_not_nil assigns(:project)
325
    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
326 441:cbce1fd3b1b7 Chris
327 37:94944d00e43c chris
    assert_tag 'li', :content => /Development status/
328
  end
329
330
  def test_show_should_not_display_hidden_custom_fields
331
    ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
332
    get :show, :id => 'ecookbook'
333
    assert_response :success
334
    assert_template 'show'
335
    assert_not_nil assigns(:project)
336 441:cbce1fd3b1b7 Chris
337 37:94944d00e43c chris
    assert_no_tag 'li', :content => /Development status/
338 0:513646585e45 Chris
  end
339 441:cbce1fd3b1b7 Chris
340 0:513646585e45 Chris
  def test_show_should_not_fail_when_custom_values_are_nil
341
    project = Project.find_by_identifier('ecookbook')
342
    project.custom_values.first.update_attribute(:value, nil)
343
    get :show, :id => 'ecookbook'
344
    assert_response :success
345
    assert_template 'show'
346
    assert_not_nil assigns(:project)
347
    assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
348
  end
349 441:cbce1fd3b1b7 Chris
350 37:94944d00e43c chris
  def show_archived_project_should_be_denied
351
    project = Project.find_by_identifier('ecookbook')
352
    project.archive!
353 441:cbce1fd3b1b7 Chris
354 37:94944d00e43c chris
    get :show, :id => 'ecookbook'
355
    assert_response 403
356
    assert_nil assigns(:project)
357
    assert_tag :tag => 'p', :content => /archived/
358
  end
359 441:cbce1fd3b1b7 Chris
360 0:513646585e45 Chris
  def test_private_subprojects_hidden
361
    get :show, :id => 'ecookbook'
362
    assert_response :success
363
    assert_template 'show'
364
    assert_no_tag :tag => 'a', :content => /Private child/
365
  end
366
367
  def test_private_subprojects_visible
368
    @request.session[:user_id] = 2 # manager who is a member of the private subproject
369
    get :show, :id => 'ecookbook'
370
    assert_response :success
371
    assert_template 'show'
372
    assert_tag :tag => 'a', :content => /Private child/
373
  end
374 441:cbce1fd3b1b7 Chris
375 0:513646585e45 Chris
  def test_settings
376
    @request.session[:user_id] = 2 # manager
377
    get :settings, :id => 1
378
    assert_response :success
379
    assert_template 'settings'
380
  end
381 441:cbce1fd3b1b7 Chris
382 22:40f7cfd4df19 chris
  def test_update
383 0:513646585e45 Chris
    @request.session[:user_id] = 2 # manager
384 22:40f7cfd4df19 chris
    post :update, :id => 1, :project => {:name => 'Test changed name',
385 0:513646585e45 Chris
                                       :issue_custom_field_ids => ['']}
386 37:94944d00e43c chris
    assert_redirected_to '/projects/ecookbook/settings'
387 0:513646585e45 Chris
    project = Project.find(1)
388
    assert_equal 'Test changed name', project.name
389
  end
390 119:8661b858af72 Chris
391
  def test_modules
392
    @request.session[:user_id] = 2
393
    Project.find(1).enabled_module_names = ['issue_tracking', 'news']
394 441:cbce1fd3b1b7 Chris
395 119:8661b858af72 Chris
    post :modules, :id => 1, :enabled_module_names => ['issue_tracking', 'repository', 'documents']
396
    assert_redirected_to '/projects/ecookbook/settings/modules'
397
    assert_equal ['documents', 'issue_tracking', 'repository'], Project.find(1).enabled_module_names.sort
398
  end
399
400
  def test_modules_should_not_allow_get
401
    @request.session[:user_id] = 1
402
    get :modules, :id => 1
403
    assert_response :method_not_allowed
404
  end
405 441:cbce1fd3b1b7 Chris
406 0:513646585e45 Chris
  def test_get_destroy
407
    @request.session[:user_id] = 1 # admin
408
    get :destroy, :id => 1
409
    assert_response :success
410
    assert_template 'destroy'
411
    assert_not_nil Project.find_by_id(1)
412
  end
413
414
  def test_post_destroy
415
    @request.session[:user_id] = 1 # admin
416
    post :destroy, :id => 1, :confirm => 1
417 37:94944d00e43c chris
    assert_redirected_to '/admin/projects'
418 0:513646585e45 Chris
    assert_nil Project.find_by_id(1)
419
  end
420 441:cbce1fd3b1b7 Chris
421 0:513646585e45 Chris
  def test_archive
422
    @request.session[:user_id] = 1 # admin
423
    post :archive, :id => 1
424 37:94944d00e43c chris
    assert_redirected_to '/admin/projects'
425 0:513646585e45 Chris
    assert !Project.find(1).active?
426
  end
427 441:cbce1fd3b1b7 Chris
428 0:513646585e45 Chris
  def test_unarchive
429
    @request.session[:user_id] = 1 # admin
430
    Project.find(1).archive
431
    post :unarchive, :id => 1
432 37:94944d00e43c chris
    assert_redirected_to '/admin/projects'
433 0:513646585e45 Chris
    assert Project.find(1).active?
434
  end
435 441:cbce1fd3b1b7 Chris
436 0:513646585e45 Chris
  def test_project_breadcrumbs_should_be_limited_to_3_ancestors
437
    CustomField.delete_all
438
    parent = nil
439
    6.times do |i|
440
      p = Project.create!(:name => "Breadcrumbs #{i}", :identifier => "breadcrumbs-#{i}")
441
      p.set_parent!(parent)
442
      get :show, :id => p
443
      assert_tag :h1, :parent => { :attributes => {:id => 'header'}},
444
                      :children => { :count => [i, 3].min,
445
                                     :only => { :tag => 'a' } }
446 441:cbce1fd3b1b7 Chris
447 0:513646585e45 Chris
      parent = p
448
    end
449
  end
450
451 441:cbce1fd3b1b7 Chris
  def test_get_copy
452 0:513646585e45 Chris
    @request.session[:user_id] = 1 # admin
453
    get :copy, :id => 1
454
    assert_response :success
455
    assert_template 'copy'
456
    assert assigns(:project)
457
    assert_equal Project.find(1).description, assigns(:project).description
458
    assert_nil assigns(:project).id
459 441:cbce1fd3b1b7 Chris
460
    assert_tag :tag => 'input',
461
      :attributes => {:name => 'project[enabled_module_names][]', :value => 'issue_tracking'}
462 0:513646585e45 Chris
  end
463
464 441:cbce1fd3b1b7 Chris
  def test_get_copy_without_project
465 0:513646585e45 Chris
    @request.session[:user_id] = 1 # admin
466
    get :copy
467
    assert_response :redirect
468
    assert_redirected_to :controller => 'admin', :action => 'projects'
469
  end
470
471 441:cbce1fd3b1b7 Chris
  def test_post_copy_should_copy_requested_items
472
    @request.session[:user_id] = 1 # admin
473
    CustomField.delete_all
474 37:94944d00e43c chris
475 441:cbce1fd3b1b7 Chris
    assert_difference 'Project.count' do
476
      post :copy, :id => 1,
477
        :project => {
478
          :name => 'Copy',
479
          :identifier => 'unique-copy',
480
          :tracker_ids => ['1', '2', '3', ''],
481
          :enabled_module_names => %w(issue_tracking time_tracking)
482
        },
483
        :only => %w(issues versions)
484 37:94944d00e43c chris
    end
485 441:cbce1fd3b1b7 Chris
    project = Project.find('unique-copy')
486
    source = Project.find(1)
487
    assert_equal %w(issue_tracking time_tracking), project.enabled_module_names.sort
488
489
    assert_equal source.versions.count, project.versions.count, "All versions were not copied"
490
    # issues assigned to a closed version won't be copied
491
    assert_equal source.issues.select {|i| i.fixed_version.nil? || i.fixed_version.open?}.size,
492
                 project.issues.count, "All issues were not copied"
493
    assert_equal 0, project.members.count
494
  end
495
496
  def test_post_copy_should_redirect_to_settings_when_successful
497
    @request.session[:user_id] = 1 # admin
498
    post :copy, :id => 1, :project => {:name => 'Copy', :identifier => 'unique-copy'}
499
    assert_response :redirect
500
    assert_redirected_to :controller => 'projects', :action => 'settings', :id => 'unique-copy'
501 37:94944d00e43c chris
  end
502
503 0:513646585e45 Chris
  def test_jump_should_redirect_to_active_tab
504
    get :show, :id => 1, :jump => 'issues'
505 37:94944d00e43c chris
    assert_redirected_to '/projects/ecookbook/issues'
506 0:513646585e45 Chris
  end
507 441:cbce1fd3b1b7 Chris
508 0:513646585e45 Chris
  def test_jump_should_not_redirect_to_inactive_tab
509
    get :show, :id => 3, :jump => 'documents'
510
    assert_response :success
511
    assert_template 'show'
512
  end
513 441:cbce1fd3b1b7 Chris
514 0:513646585e45 Chris
  def test_jump_should_not_redirect_to_unknown_tab
515
    get :show, :id => 3, :jump => 'foobar'
516
    assert_response :success
517
    assert_template 'show'
518
  end
519
520
  # A hook that is manually registered later
521
  class ProjectBasedTemplate < Redmine::Hook::ViewListener
522
    def view_layouts_base_html_head(context)
523
      # Adds a project stylesheet
524
      stylesheet_link_tag(context[:project].identifier) if context[:project]
525
    end
526
  end
527
  # Don't use this hook now
528
  Redmine::Hook.clear_listeners
529 441:cbce1fd3b1b7 Chris
530 0:513646585e45 Chris
  def test_hook_response
531
    Redmine::Hook.add_listener(ProjectBasedTemplate)
532
    get :show, :id => 1
533
    assert_tag :tag => 'link', :attributes => {:href => '/stylesheets/ecookbook.css'},
534
                               :parent => {:tag => 'head'}
535 441:cbce1fd3b1b7 Chris
536 0:513646585e45 Chris
    Redmine::Hook.clear_listeners
537
  end
538
end