0

I'm trying to test an app that creates some custom permissions during intialization. These are created right after database creation:

custom_permissions = getattr(settings,'SOMEAPP_PERMISSIONS',() )

def create_custom_permissions(sender, **kwargs):
    ct, created = ContentType.objects.get_or_create(model = '',
                                                    app_label = 'some_app',
                                                    defaults = {'name':'some_app'})

    for codename, name in custom_permissions: 
        perm = Permission.objects.get_or_create(codename = codename,
                                         content_type__pk = ct.id,
                                         name = name)

post_save.connect(create_custom_permissions, Permission)

All the discussions i can find for overriding settings are somewhat related to override_settings,with self.settings and so on. But when i override the settings during a TestCase, my function has already been run, and the change of the settings has, of course, no effect:

@override_settings(SOMEAPP_PERMISSIONS = (('some_custom_permission','No Name'))
class TestCustomPermissions(TestCase):

    fixtures = ['some_app_user_fixture.json']
    urls = 'some_app.tests.test_urls'

    def test_create_point_privileges(self):
        """ check if all necessary privileges have been created """
        Permission.objects.get(codename = 'some_custom_permission')

And therefore all my tests fail. Now how can i use a settings file just for testing this special function and it's tie to the creation of the Database?

marue
  • 5,588
  • 7
  • 37
  • 65

1 Answers1

1

Something you'll see from one Django project to another is that you'll have a separate settings module provided that supplies test configurations/overrides:

# project/settings.py
SOMEAPP_PERMISSIONS = (
    'foo', 'bar'
)

# project/test.py
from project.settings import *

SOMEAPP_PERMISSIONS = (
    'bar', 'baz'
)

All you'd have to do now is provide the settings option when your run the management command: python ./manage.py test --settings=project.test. It's simple, effective and self-documenting.

Filip Dupanović
  • 32,650
  • 13
  • 84
  • 114
  • Allready very helpfull, but can't i force the use of these settings programmatically? I would prefer that. – marue May 01 '12 at 16:11
  • Since your listening to `signals.post_save` and not `signals.post_syncdb`, as you should be, all you need to do is simply save a `Permission` object before your test and it will pass. `SOMEAPP_PERMISSIONS += ('bar', 'baz')` would be perfect for you and there's always a way to avoid dynamically configuring your project configuration while the test runner is collecting results. If you were listening to `signals.post_syncdb`, you'd even have to run `management.call_command('syncdb')` with settings overrides/rollbacks in `setup()`/`teardown()` both, where I'm sure you'd loose fans on the team! – Filip Dupanović May 01 '12 at 16:40
  • No, that is not working, as the line `custom_permissions=getattr(settings,'SOMEAPP_PERMISSIONS',())` is outside the function and gets initialized once when the module is loaded. So it will return `()`, even when i have overridden the settings in the meantime. Looks like this is pretty tricky... – marue May 01 '12 at 16:58
  • There's nothing preventing you to override `custom_permissions` in the module and to perform a rollback later on. – Filip Dupanović May 01 '12 at 17:12
  • Yey, will stick with that. Thanks for the efforts. – marue May 01 '12 at 18:16