Commit da84575ee29154fa4f24c9acdfce9ec16a7acb5b

Authored by Braulio Bhavamitra
1 parent 8a3fb6f3

plugins: only call event on plugin if it is defined

This allow proper use of default values defined in Noosfero::Plugin
abstract class.
lib/noosfero/plugin/manager.rb
... ... @@ -20,15 +20,15 @@ class Noosfero::Plugin::Manager
20 20 # return [1,0,1,2,3]
21 21 #
22 22 def dispatch(event, *args)
23   - dispatch_without_flatten(event, *args).flatten
  23 + flat_map{ |plugin| result_for plugin, event, *args }.compact
24 24 end
25 25  
26 26 def fetch_plugins(event, *args)
27   - map { |plugin| plugin.class if plugin.send(event, *args) }.compact.flatten
  27 + map { |plugin| plugin.class if result_for plugin, event, *args }.compact.flatten
28 28 end
29 29  
30 30 def dispatch_without_flatten(event, *args)
31   - map { |plugin| plugin.send(event, *args) }.compact
  31 + map { |plugin| result_for plugin, event, *args }.compact
32 32 end
33 33  
34 34 alias :dispatch_scopes :dispatch_without_flatten
... ... @@ -37,9 +37,14 @@ class Noosfero::Plugin::Manager
37 37 Noosfero::Plugin.new.send event, *args
38 38 end
39 39  
  40 + def result_for plugin, event, *args
  41 + method = plugin.method event
  42 + method.call *args if method.owner != Noosfero::Plugin
  43 + end
  44 +
40 45 def dispatch_first(event, *args)
41 46 each do |plugin|
42   - result = plugin.send(event, *args)
  47 + result = result_for plugin, event, *args
43 48 return result if result.present?
44 49 end
45 50 default_for event, *args
... ... @@ -47,7 +52,7 @@ class Noosfero::Plugin::Manager
47 52  
48 53 def fetch_first_plugin(event, *args)
49 54 each do |plugin|
50   - result = plugin.send event, *args
  55 + result = result_for plugin, event, *args
51 56 return plugin.class if result.present?
52 57 end
53 58 nil
... ... @@ -55,7 +60,7 @@ class Noosfero::Plugin::Manager
55 60  
56 61 def pipeline(event, *args)
57 62 each do |plugin|
58   - result = plugin.send(event, *args)
  63 + result = result_for plugin, event, *args
59 64 result = result.kind_of?(Array) ? result : [result]
60 65 raise ArgumentError, "Pipeline broken by #{plugin.class.name} on #{event} with #{result.length} arguments instead of #{args.length}." if result.length != args.length
61 66 args = result
... ... @@ -64,7 +69,7 @@ class Noosfero::Plugin::Manager
64 69 end
65 70  
66 71 def filter(property, data)
67   - inject(data) {|data, plugin| data = plugin.send(property, data)}
  72 + inject(data){ |data, plugin| data = plugin.send(property, data) }
68 73 end
69 74  
70 75 def parse_macro(macro_name, macro, source = nil)
... ...
test/unit/plugin_manager_test.rb
... ... @@ -304,4 +304,31 @@ class PluginManagerTest < ActiveSupport::TestCase
304 304 @manager.dispatch_first :find_by_contents, :products, environment.products, 'product'
305 305 end
306 306  
  307 + should 'not event if it is not defined by plugin' do
  308 + class Noosfero::Plugin
  309 + def never_call
  310 + nil
  311 + end
  312 + end
  313 + class Plugin1 < Noosfero::Plugin
  314 + def never_call
  315 + 'defined'
  316 + end
  317 + end
  318 + class Plugin2 < Noosfero::Plugin
  319 + end
  320 + Noosfero::Plugin.stubs(:all).returns(['PluginManagerTest::Plugin1', 'PluginManagerTest::Plugin2'])
  321 + environment.enable_plugin(Plugin1)
  322 + environment.enable_plugin(Plugin2)
  323 + plugin1 = @manager.enabled_plugins.detect{ |p| p.is_a? Plugin1 }
  324 + plugin2 = @manager.enabled_plugins.detect{ |p| p.is_a? Plugin2 }
  325 +
  326 + assert_equal Plugin1, Plugin1.new.method(:never_call).owner
  327 + assert_equal Noosfero::Plugin, Plugin2.new.method(:never_call).owner
  328 + # expects never can't be used as it defines the method
  329 + @manager.expects(:result_for).with(plugin1, :never_call).returns(Plugin1.new.never_call)
  330 + @manager.expects(:result_for).with(plugin2, :never_call).returns(nil)
  331 + @manager.dispatch :never_call
  332 + end
  333 +
307 334 end
... ...