#######################
Testing Your Extensions
#######################

************
Testing Apps
************

Resolving View Names
====================

Your apps need testing, but in your live site they aren't in ``urls.py`` as
they are attached to a CMS page.  So if you want to be able to use
:func:`~django.core.urlresolvers.reverse` in your tests, or test templates that
use the :ttag:`url` template tag, you need to hook up your app to a special
test version of ``urls.py`` and tell your tests to use that.

So you could create ``myapp/tests/urls.py`` with the following code::

    from django.contrib import admin
    from django.conf.urls import url, patterns, include

    urlpatterns = patterns('',
        url(r'^admin/', include(admin.site.urls)),
        url(r'^myapp/', include('myapp.urls')),
        url(r'', include('cms.urls')),
    )

And then in your tests you can plug this in with the
:func:`~django.test.utils.override_settings` decorator::

    from django.test.utils import override_settings
    from cms.test_utils.testcases import CMSTestCase

    class MyappTests(CMSTestCase):

        @override_settings(ROOT_URLCONF='myapp.tests.urls')
        def test_myapp_page(self):
            test_url = reverse('myapp_view_name')
            # rest of test as normal

If you want to the test url conf throughout your test class, then you can use
apply the decorator to the whole class::

    from django.test.utils import override_settings
    from cms.test_utils.testcases import CMSTestCase

    @override_settings(ROOT_URLCONF='myapp.tests.urls')
    class MyappTests(CMSTestCase):

        def test_myapp_page(self):
            test_url = reverse('myapp_view_name')
            # rest of test as normal

CMSTestCase
===========

Django CMS includes ``CMSTestCase`` which has various utility methods that
might be useful for testing your CMS app and manipulating CMS pages.

***************
Testing Plugins
***************

To test plugins, you need to assign them to a placeholder. Depending on at what
level you want to test your plugin, you can either check the HTML generated by
it or the context provided to its template::


    from django.test import TestCase

    from cms.api import add_plugin
    from cms.models import Placeholder

    from myapp.cms_plugins import MyPlugin
    from myapp.models import MyappPlugin

    class MypluginTests(TestCase):
        def test_plugin_context(self):
            placeholder = Placeholder.objects.create(slot='test')
            model_instance = add_plugin(
                placeholder,
                MyPlugin,
                'en',
            )
            plugin_instance = model_instance.get_plugin_class_instance()
            context = plugin_instance.render({}, model_instance, None)
            self.assertIn('key', context)
            self.assertEqual(context['key'], 'value')

        def test_plugin_html(self):
            placeholder = Placeholder.objects.create(slot='test')
            model_instance = add_plugin(
                placeholder,
                MyPlugin,
                'en',
            )
            html = model_instance.render_plugin({})
            self.assertEqual(html, '<strong>Test</strong>')
