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 validate
import VdtTypeError
24 from mediagoblin
import mg_globals
25 from mediagoblin
.init
.plugins
import setup_plugins
26 from mediagoblin
.init
.config
import read_mediagoblin_config
27 from mediagoblin
.tools
import pluginapi
28 from mediagoblin
.tests
.tools
import get_app
31 def with_cleanup(*modules_to_delete
):
32 def _with_cleanup(fun
):
33 """Wrapper that saves and restores mg_globals"""
34 def _with_cleanup_inner(*args
, **kwargs
):
35 old_app_config
= mg_globals
.app_config
36 old_global_config
= mg_globals
.global_config
37 # Need to delete icky modules before and after so as to make
38 # sure things work correctly.
39 for module
in modules_to_delete
:
41 del sys
.modules
[module
]
44 # The plugin cache gets populated as a side-effect of
45 # importing, so it's best to clear it before and after a test.
46 pman
= pluginapi
.PluginManager()
49 return fun(*args
, **kwargs
)
51 mg_globals
.app_config
= old_app_config
52 mg_globals
.global_config
= old_global_config
53 # Need to delete icky modules before and after so as to make
54 # sure things work correctly.
55 for module
in modules_to_delete
:
57 del sys
.modules
[module
]
62 _with_cleanup_inner
.__name
__ = fun
.__name
__
63 return _with_cleanup_inner
67 def build_config(sections
):
68 """Builds a ConfigObj object with specified data
70 :arg sections: list of ``(section_name, section_data,
71 subsection_list)`` tuples where section_data is a dict and
72 subsection_list is a list of ``(section_name, section_data,
73 subsection_list)``, ...
78 ... ('mediagoblin', {'key1': 'val1'}, []),
79 ... ('section2', {}, [
80 ... ('subsection1', {}, [])
86 def _iter_section(cfg
, section_list
):
87 for section_name
, data
, subsection_list
in section_list
:
88 cfg
[section_name
] = data
89 _iter_section(cfg
[section_name
], subsection_list
)
91 _iter_section(cfg
, sections
)
96 def test_no_plugins():
97 """Run setup_plugins with no plugins in config"""
98 cfg
= build_config([('mediagoblin', {}, [])])
99 mg_globals
.app_config
= cfg
['mediagoblin']
100 mg_globals
.global_config
= cfg
102 pman
= pluginapi
.PluginManager()
105 # Make sure we didn't load anything.
106 assert len(pman
.plugins
) == 0
109 @with_cleanup('mediagoblin.plugins.sampleplugin')
110 def test_one_plugin():
111 """Run setup_plugins with a single working plugin"""
113 ('mediagoblin', {}, []),
115 ('mediagoblin.plugins.sampleplugin', {}, [])
119 mg_globals
.app_config
= cfg
['mediagoblin']
120 mg_globals
.global_config
= cfg
122 pman
= pluginapi
.PluginManager()
125 # Make sure we only found one plugin
126 assert len(pman
.plugins
) == 1
127 # Make sure the plugin is the one we think it is.
128 assert pman
.plugins
[0] == 'mediagoblin.plugins.sampleplugin'
129 # Make sure there was one hook registered
130 assert len(pman
.hooks
) == 1
131 # Make sure _setup_plugin_called was called once
132 import mediagoblin
.plugins
.sampleplugin
133 assert mediagoblin
.plugins
.sampleplugin
._setup
_plugin
_called
== 1
136 @with_cleanup('mediagoblin.plugins.sampleplugin')
137 def test_same_plugin_twice():
138 """Run setup_plugins with a single working plugin twice"""
140 ('mediagoblin', {}, []),
142 ('mediagoblin.plugins.sampleplugin', {}, []),
143 ('mediagoblin.plugins.sampleplugin', {}, []),
147 mg_globals
.app_config
= cfg
['mediagoblin']
148 mg_globals
.global_config
= cfg
150 pman
= pluginapi
.PluginManager()
153 # Make sure we only found one plugin
154 assert len(pman
.plugins
) == 1
155 # Make sure the plugin is the one we think it is.
156 assert pman
.plugins
[0] == 'mediagoblin.plugins.sampleplugin'
157 # Make sure there was one hook registered
158 assert len(pman
.hooks
) == 1
159 # Make sure _setup_plugin_called was called once
160 import mediagoblin
.plugins
.sampleplugin
161 assert mediagoblin
.plugins
.sampleplugin
._setup
_plugin
_called
== 1
165 def test_disabled_plugin():
166 """Run setup_plugins with a single working plugin twice"""
168 ('mediagoblin', {}, []),
170 ('-mediagoblin.plugins.sampleplugin', {}, []),
174 mg_globals
.app_config
= cfg
['mediagoblin']
175 mg_globals
.global_config
= cfg
177 pman
= pluginapi
.PluginManager()
180 # Make sure we didn't load the plugin
181 assert len(pman
.plugins
) == 0
184 CONFIG_ALL_CALLABLES
= [
185 ('mediagoblin', {}, []),
187 ('mediagoblin.tests.testplugins.callables1', {}, []),
188 ('mediagoblin.tests.testplugins.callables2', {}, []),
189 ('mediagoblin.tests.testplugins.callables3', {}, []),
195 def test_hook_handle():
197 Test the hook_handle method
199 cfg
= build_config(CONFIG_ALL_CALLABLES
)
201 mg_globals
.app_config
= cfg
['mediagoblin']
202 mg_globals
.global_config
= cfg
206 # Just one hook provided
208 assert pluginapi
.hook_handle(
209 "just_one", call_log
) == "Called just once"
210 assert call_log
== ["expect this one call"]
212 # Nothing provided and unhandled not okay
214 pluginapi
.hook_handle(
215 "nothing_handling", call_log
) == None
216 assert call_log
== []
218 # Nothing provided and unhandled okay
220 assert pluginapi
.hook_handle(
221 "nothing_handling", call_log
, unhandled_okay
=True) is None
222 assert call_log
== []
224 # Multiple provided, go with the first!
226 assert pluginapi
.hook_handle(
227 "multi_handle", call_log
) == "the first returns"
228 assert call_log
== ["Hi, I'm the first"]
230 # Multiple provided, one has CantHandleIt
232 assert pluginapi
.hook_handle(
233 "multi_handle_with_canthandle",
234 call_log
) == "the second returns"
235 assert call_log
== ["Hi, I'm the second"]
239 def test_hook_runall():
241 Test the hook_runall method
243 cfg
= build_config(CONFIG_ALL_CALLABLES
)
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
292 cfg
= build_config(CONFIG_ALL_CALLABLES
)
294 mg_globals
.app_config
= cfg
['mediagoblin']
295 mg_globals
.global_config
= cfg
299 assert pluginapi
.hook_transform(
300 "expand_tuple", (-1, 0)) == (-1, 0, 1, 2, 3)
303 def test_plugin_config():
305 Make sure plugins can set up their own config
307 config
, validation_result
= read_mediagoblin_config(
308 pkg_resources
.resource_filename(
309 'mediagoblin.tests', 'appconfig_plugin_specs.ini'))
311 pluginspec_section
= config
['plugins'][
312 'mediagoblin.tests.testplugins.pluginspec']
313 assert pluginspec_section
['some_string'] == 'not blork'
314 assert pluginspec_section
['dont_change_me'] == 'still the default'
316 # Make sure validation works... this should be an error
320 'mediagoblin.tests.testplugins.pluginspec'][
324 # the callables thing shouldn't really have anything though.
325 assert len(config
['plugins'][
326 'mediagoblin.tests.testplugins.callables1']) == 0
330 def context_modified_app(request
):
332 Get a MediaGoblin app fixture using appconfig_context_modified.ini
336 mgoblin_config
=pkg_resources
.resource_filename(
337 'mediagoblin.tests', 'appconfig_context_modified.ini'))
340 def test_modify_context(context_modified_app
):
342 Test that we can modify both the view/template specific and
343 global contexts for templates.
345 # Specific thing passed into a page
346 result
= context_modified_app
.get("/modify_context/specific/")
347 assert result
.body
.strip() == """Specific page!
349 specific thing: in yer specificpage
350 global thing: globally appended!
352 doubleme: happyhappy"""
354 # General test, should have global context variable only
355 result
= context_modified_app
.get("/modify_context/")
356 assert result
.body
.strip() == """General page!
358 global thing: globally appended!