1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # 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 Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 from configobj
import ConfigObj
22 from mediagoblin
import mg_globals
23 from mediagoblin
.init
.plugins
import setup_plugins
24 from mediagoblin
.tools
import pluginapi
27 def with_cleanup(*modules_to_delete
):
28 def _with_cleanup(fun
):
29 """Wrapper that saves and restores mg_globals"""
30 def _with_cleanup_inner(*args
, **kwargs
):
31 old_app_config
= mg_globals
.app_config
32 old_global_config
= mg_globals
.global_config
33 # Need to delete icky modules before and after so as to make
34 # sure things work correctly.
35 for module
in modules_to_delete
:
37 del sys
.modules
[module
]
40 # The plugin cache gets populated as a side-effect of
41 # importing, so it's best to clear it before and after a test.
42 pman
= pluginapi
.PluginManager()
45 return fun(*args
, **kwargs
)
47 mg_globals
.app_config
= old_app_config
48 mg_globals
.global_config
= old_global_config
49 # Need to delete icky modules before and after so as to make
50 # sure things work correctly.
51 for module
in modules_to_delete
:
53 del sys
.modules
[module
]
58 _with_cleanup_inner
.__name
__ = fun
.__name
__
59 return _with_cleanup_inner
63 def build_config(sections
):
64 """Builds a ConfigObj object with specified data
66 :arg sections: list of ``(section_name, section_data,
67 subsection_list)`` tuples where section_data is a dict and
68 subsection_list is a list of ``(section_name, section_data,
69 subsection_list)``, ...
74 ... ('mediagoblin', {'key1': 'val1'}, []),
75 ... ('section2', {}, [
76 ... ('subsection1', {}, [])
82 def _iter_section(cfg
, section_list
):
83 for section_name
, data
, subsection_list
in section_list
:
84 cfg
[section_name
] = data
85 _iter_section(cfg
[section_name
], subsection_list
)
87 _iter_section(cfg
, sections
)
92 def test_no_plugins():
93 """Run setup_plugins with no plugins in config"""
94 cfg
= build_config([('mediagoblin', {}, [])])
95 mg_globals
.app_config
= cfg
['mediagoblin']
96 mg_globals
.global_config
= cfg
98 pman
= pluginapi
.PluginManager()
101 # Make sure we didn't load anything.
102 assert len(pman
.plugins
) == 0
105 @with_cleanup('mediagoblin.plugins.sampleplugin')
106 def test_one_plugin():
107 """Run setup_plugins with a single working plugin"""
109 ('mediagoblin', {}, []),
111 ('mediagoblin.plugins.sampleplugin', {}, [])
115 mg_globals
.app_config
= cfg
['mediagoblin']
116 mg_globals
.global_config
= cfg
118 pman
= pluginapi
.PluginManager()
121 # Make sure we only found one plugin
122 assert len(pman
.plugins
) == 1
123 # Make sure the plugin is the one we think it is.
124 assert pman
.plugins
[0] == 'mediagoblin.plugins.sampleplugin'
125 # Make sure there was one hook registered
126 assert len(pman
.hooks
) == 1
127 # Make sure _setup_plugin_called was called once
128 import mediagoblin
.plugins
.sampleplugin
129 assert mediagoblin
.plugins
.sampleplugin
._setup
_plugin
_called
== 1
132 @with_cleanup('mediagoblin.plugins.sampleplugin')
133 def test_same_plugin_twice():
134 """Run setup_plugins with a single working plugin twice"""
136 ('mediagoblin', {}, []),
138 ('mediagoblin.plugins.sampleplugin', {}, []),
139 ('mediagoblin.plugins.sampleplugin', {}, []),
143 mg_globals
.app_config
= cfg
['mediagoblin']
144 mg_globals
.global_config
= cfg
146 pman
= pluginapi
.PluginManager()
149 # Make sure we only found one plugin
150 assert len(pman
.plugins
) == 1
151 # Make sure the plugin is the one we think it is.
152 assert pman
.plugins
[0] == 'mediagoblin.plugins.sampleplugin'
153 # Make sure there was one hook registered
154 assert len(pman
.hooks
) == 1
155 # Make sure _setup_plugin_called was called once
156 import mediagoblin
.plugins
.sampleplugin
157 assert mediagoblin
.plugins
.sampleplugin
._setup
_plugin
_called
== 1
161 def test_disabled_plugin():
162 """Run setup_plugins with a single working plugin twice"""
164 ('mediagoblin', {}, []),
166 ('-mediagoblin.plugins.sampleplugin', {}, []),
170 mg_globals
.app_config
= cfg
['mediagoblin']
171 mg_globals
.global_config
= cfg
173 pman
= pluginapi
.PluginManager()
176 # Make sure we didn't load the plugin
177 assert len(pman
.plugins
) == 0
181 def test_hook_handle():
183 Test the hook_handle method
186 ('mediagoblin', {}, []),
188 ('mediagoblin.tests.testplugins.callables1', {}, []),
189 ('mediagoblin.tests.testplugins.callables2', {}, []),
190 ('mediagoblin.tests.testplugins.callables3', {}, []),
194 mg_globals
.app_config
= cfg
['mediagoblin']
195 mg_globals
.global_config
= cfg
199 # Just one hook provided
201 assert pluginapi
.hook_handle(
202 "just_one", call_log
) == "Called just once"
203 assert call_log
== ["expect this one call"]
205 # Nothing provided and unhandled not okay
207 pluginapi
.hook_handle(
208 "nothing_handling", call_log
) == None
209 assert call_log
== []
211 # Nothing provided and unhandled okay
213 assert pluginapi
.hook_handle(
214 "nothing_handling", call_log
, unhandled_okay
=True) is None
215 assert call_log
== []
217 # Multiple provided, go with the first!
219 assert pluginapi
.hook_handle(
220 "multi_handle", call_log
) == "the first returns"
221 assert call_log
== ["Hi, I'm the first"]
223 # Multiple provided, one has CantHandleIt
225 assert pluginapi
.hook_handle(
226 "multi_handle_with_canthandle",
227 call_log
) == "the second returns"
228 assert call_log
== ["Hi, I'm the second"]
232 def test_hook_runall():
234 Test the hook_runall method
237 ('mediagoblin', {}, []),
239 ('mediagoblin.tests.testplugins.callables1', {}, []),
240 ('mediagoblin.tests.testplugins.callables2', {}, []),
241 ('mediagoblin.tests.testplugins.callables3', {}, []),
245 mg_globals
.app_config
= cfg
['mediagoblin']
246 mg_globals
.global_config
= cfg
250 # Just one hook, check results
252 assert pluginapi
.hook_runall(
253 "just_one", call_log
) == ["Called just once"]
254 assert call_log
== ["expect this one call"]
256 # None provided, check results
258 assert pluginapi
.hook_runall(
259 "nothing_handling", call_log
) == []
260 assert call_log
== []
262 # Multiple provided, check results
264 assert pluginapi
.hook_runall(
265 "multi_handle", call_log
) == [
267 "the second returns",
272 "Hi, I'm the second",
275 # Multiple provided, one has CantHandleIt, check results
277 assert pluginapi
.hook_runall(
278 "multi_handle_with_canthandle", call_log
) == [
279 "the second returns",
283 "Hi, I'm the second",
288 def test_hook_transform():
290 Test the hook_transform method
293 ('mediagoblin', {}, []),
295 ('mediagoblin.tests.testplugins.callables1', {}, []),
296 ('mediagoblin.tests.testplugins.callables2', {}, []),
297 ('mediagoblin.tests.testplugins.callables3', {}, []),
301 mg_globals
.app_config
= cfg
['mediagoblin']
302 mg_globals
.global_config
= cfg
306 assert pluginapi
.hook_transform(
307 "expand_tuple", (-1, 0)) == (-1, 0, 1, 2, 3)