@@ -178,7 +178,11 module Redmine | |||
|
178 | 178 | when Hash |
|
179 | 179 | project.nil? ? item.url : {item.param => project}.merge(item.url) |
|
180 | 180 | when Symbol |
|
181 | send(item.url) | |
|
181 | if project | |
|
182 | send(item.url, project) | |
|
183 | else | |
|
184 | send(item.url) | |
|
185 | end | |
|
182 | 186 | else |
|
183 | 187 | item.url |
|
184 | 188 | end |
@@ -376,9 +380,9 module Redmine | |||
|
376 | 380 | |
|
377 | 381 | class MenuItem < MenuNode |
|
378 | 382 | include Redmine::I18n |
|
379 | attr_reader :name, :url, :param, :condition, :parent, :child_menus, :last | |
|
383 | attr_reader :name, :url, :param, :condition, :parent, :child_menus, :last, :permission | |
|
380 | 384 | |
|
381 | def initialize(name, url, options) | |
|
385 | def initialize(name, url, options={}) | |
|
382 | 386 | raise ArgumentError, "Invalid option :if for menu item '#{name}'" if options[:if] && !options[:if].respond_to?(:call) |
|
383 | 387 | raise ArgumentError, "Invalid option :html for menu item '#{name}'" if options[:html] && !options[:html].is_a?(Hash) |
|
384 | 388 | raise ArgumentError, "Cannot set the :parent to be the same as this item" if options[:parent] == name.to_sym |
@@ -386,6 +390,8 module Redmine | |||
|
386 | 390 | @name = name |
|
387 | 391 | @url = url |
|
388 | 392 | @condition = options[:if] |
|
393 | @permission = options[:permission] | |
|
394 | @permission ||= false if options.key?(:permission) | |
|
389 | 395 | @param = options[:param] || :id |
|
390 | 396 | @caption = options[:caption] |
|
391 | 397 | @html_options = options[:html] || {} |
@@ -423,11 +429,19 module Redmine | |||
|
423 | 429 | |
|
424 | 430 | # Checks if a user is allowed to access the menu item by: |
|
425 | 431 | # |
|
426 | # * Checking the url target (project only) | |
|
432 | # * Checking the permission or the url target (project only) | |
|
427 | 433 | # * Checking the conditions of the item |
|
428 | 434 | def allowed?(user, project) |
|
429 | if url.is_a?(Hash) && project && user && !user.allowed_to?(url, project) | |
|
430 | return false | |
|
435 | if user && project | |
|
436 | if permission | |
|
437 | unless user.allowed_to?(permission, project) | |
|
438 | return false | |
|
439 | end | |
|
440 | elsif permission.nil? && url.is_a?(Hash) | |
|
441 | unless user.allowed_to?(url, project) | |
|
442 | return false | |
|
443 | end | |
|
444 | end | |
|
431 | 445 | end |
|
432 | 446 | if condition && !condition.call(project) |
|
433 | 447 | # Condition that doesn't pass |
@@ -47,6 +47,20 class Redmine::MenuManager::MenuHelperTest < ActionView::TestCase | |||
|
47 | 47 | end |
|
48 | 48 | end |
|
49 | 49 | |
|
50 | def test_render_menu_node_with_symbol_as_url | |
|
51 | node = Redmine::MenuManager::MenuItem.new(:testing, :issues_path) | |
|
52 | @output_buffer = render_menu_node(node, nil) | |
|
53 | ||
|
54 | assert_select "a[href=/issues]", "Testing" | |
|
55 | end | |
|
56 | ||
|
57 | def test_render_menu_node_with_symbol_as_url_and_project | |
|
58 | node = Redmine::MenuManager::MenuItem.new(:testing, :project_issues_path) | |
|
59 | @output_buffer = render_menu_node(node, Project.find(1)) | |
|
60 | ||
|
61 | assert_select "a[href=/projects/ecookbook/issues]", "Testing" | |
|
62 | end | |
|
63 | ||
|
50 | 64 | def test_render_menu_node_with_nested_items |
|
51 | 65 | parent_node = Redmine::MenuManager::MenuItem.new(:parent_node, '/test', { }) |
|
52 | 66 | parent_node << Redmine::MenuManager::MenuItem.new(:child_one_node, '/test', { }) |
@@ -216,6 +230,19 class Redmine::MenuManager::MenuHelperTest < ActionView::TestCase | |||
|
216 | 230 | assert_equal 2, items.size |
|
217 | 231 | end |
|
218 | 232 | |
|
233 | def test_menu_items_for_should_skip_items_that_fail_the_permission | |
|
234 | menu_name = :test_menu_items_for_should_skip_items_that_fail_the_permission | |
|
235 | Redmine::MenuManager.map menu_name do |menu| | |
|
236 | menu.push(:a_menu, :project_issues_path) | |
|
237 | menu.push(:unallowed, :project_issues_path, :permission => :unallowed) | |
|
238 | end | |
|
239 | ||
|
240 | User.current = User.find(2) | |
|
241 | ||
|
242 | items = menu_items_for(menu_name, Project.find(1)) | |
|
243 | assert_equal 1, items.size | |
|
244 | end | |
|
245 | ||
|
219 | 246 | def test_menu_items_for_should_skip_items_that_fail_the_conditions |
|
220 | 247 | menu_name = :test_menu_items_for_should_skip_items_that_fail_the_conditions |
|
221 | 248 | Redmine::MenuManager.map menu_name do |menu| |
@@ -46,12 +46,6 class Redmine::MenuManager::MenuItemTest < ActiveSupport::TestCase | |||
|
46 | 46 | end |
|
47 | 47 | end |
|
48 | 48 | |
|
49 | def test_new_menu_item_should_require_the_options | |
|
50 | assert_raises ArgumentError do | |
|
51 | Redmine::MenuManager::MenuItem.new(:test_missing_options, '/test') | |
|
52 | end | |
|
53 | end | |
|
54 | ||
|
55 | 49 | def test_new_menu_item_with_all_required_parameters |
|
56 | 50 | assert Redmine::MenuManager::MenuItem.new(:test_good_menu, '/test', {}) |
|
57 | 51 | end |
General Comments 0
You need to be logged in to leave comments.
Login now