{{{#!python
from django.test import TestCase
from django.test.utils import override_settings
from django.core.urlresolvers import reverse
from django.conf import settings
class OverrideSettingsTest(TestCase):
def test_a(self):
"""
Toggle this test by commenting it out and see whether test_b()
passes.
"""
response = self.client.get(reverse("harmless-view"))
self.assertEqual(response.status_code, 301)
@override_settings(LOGIN_URL="/THIS_IS_FINE/")
def test_b(self):
# settings appear to be overridden as expected
self.assertEqual(settings.LOGIN_URL, "/THIS_IS_FINE/")
response = self.client.get(reverse("redirect-to-login"))
# The following assertion fails only when test_a() is run.
self.assertRedirects(response, "/THIS_IS_FINE/",
status_code=301,
target_status_code=404
)
def test_c(self):
response = self.client.get(reverse("harmless-view"))
self.assertEqual(response.status_code, 301)
}}}
{{{
.F.
======================================================================
FAIL: test_b (override_bug.tests.OverrideSettingsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "django/test/utils.py", line 224, in inner
return test_func(*args, **kwargs)
File "override_bug/override_bug/tests.py", line 24, in test_b
target_status_code=404
File "django/test/testcases.py", line 617, in assertRedirects
(url, expected_url))
AssertionError: Response redirected to
'http://testserver/THIS/SHOULD/BE/OVERRIDDEN/IN/THE/TEST/', expected
'http://testserver/THIS_IS_FINE/'
----------------------------------------------------------------------
Ran 3 tests in 0.031s
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/21466>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* status: new => closed
* needs_docs: => 0
* resolution: => invalid
* needs_tests: => 0
* needs_better_patch: => 0
Comment:
I'm almost sure the problem is related to the way you are using
`settings.LOGIN_URL`. In your sample project, it is used as a parameter of
the `as_view` call in your URLConf, that means that it will be defined
once and for all requests at import time.
You can workaround this issue by subclassing `RedirectView` and overriding
`get_redirect_url()` so that when `settings.LOGIN_URL` changes your view
can take that change into account. I don't think we can do anything on
Django's side.
--
Ticket URL: <https://code.djangoproject.com/ticket/21466#comment:1>
Comment (by jnns):
Sorry for opening this ticket. You're right that this has nothing to do
with Django.
I used django-braces' `LoginRequiredMixin` which sets `settings.LOGIN_URL`
at import time and replicated this bug in my example project without
further reflecting upon this issue.
--
Ticket URL: <https://code.djangoproject.com/ticket/21466#comment:2>
Comment (by matthewf@…):
I think I'm hitting the same issue as well. In my project, I have set a
variable called `REGISTRATION_ENABLED`. However, when I try to override
this setting in my tests, it's never read. Changing the setting beforehand
in my settings.py makes the test pass, however. This is how it's used in
my tests:
{{{
def test_auth(self):
"""
Test that a user can register using the API, login and logout
"""
# test registration workflow
submit = {
'username': 'Otto',
'password': 'password',
'first_name': 'first_name',
'last_name': 'last_name',
'email': 'em...@email.com',
'is_superuser': False,
'is_staff': False,
}
url = '/api/auth/register'
response = self.client.post(url, json.dumps(submit),
content_type='application/json')
self.assertEqual(response.status_code, 201)
# test disabled registration
with self.settings(REGISTRATION_ENABLED=False):
submit['username'] = 'anothernewuser'
response = self.client.post(url, json.dumps(submit),
content_type='application/json')
self.assertEqual(response.status_code, 403)
}}}
And the code block in my views:
{{{
class HasRegistrationAuth(permissions.BasePermission):
"""
Checks to see if registration is enabled
"""
def has_permission(self, request, view):
return settings.REGISTRATION_ENABLED
}}}
Note that I'm using https://github.com/tomchristie/django-rest-framework
in my application.
--
Ticket URL: <https://code.djangoproject.com/ticket/21466#comment:3>
* status: closed => new
* resolution: invalid =>
Comment:
apologies, I forgot to add the output of my tests!
{{{
./manage.py test api
Creating test database for alias 'default'...
.......F....................................................
======================================================================
FAIL: test_auth (api.tests.test_auth.AuthTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/api/tests/test_auth.py", line 64, in test_auth
self.assertEqual(response.status_code, 403)
AssertionError: 201 != 403
----------------------------------------------------------------------
Ran 60 tests in 29.056s
FAILED (failures=1)
Destroying test database for alias 'default'...
}}}
When i modify the setting to `True` in settings.py, the test passes
without failure.
--
Ticket URL: <https://code.djangoproject.com/ticket/21466#comment:4>
* status: new => closed
* resolution: => invalid
Comment:
I think it's more likely that your use of `override_settings()` is
invalid. Please be sure you've read the caveats in
[https://docs.djangoproject.com/en/1.6/topics/testing/tools/#overriding-
settings the documentation] and ask questions using our
[https://code.djangoproject.com/wiki/TicketClosingReasons/UseSupportChannels
support channels]. If after doing those setps you still believe you've
found a bug, please open a new ticket, thanks.
--
Ticket URL: <https://code.djangoproject.com/ticket/21466#comment:5>