Im trying to unit test one of my views that is decorated with #verified_email_required. I am unable to find out how to set the user as having their email verified so that it will allow them to view the page and assert that it uses the correct template (creating a superuser doesnt help).
This is the error im getting
AssertionError: False is not true : Template 'enrolment/index.html' was not a template used to render the response. Actual template(s) used: account/verified_email_required.html, account/base.html, base.html
And this is my test
def test_verified_user_uses_correct_template(self):
user = User.objects.create_superuser('username')
self.client.force_login(user)
response = self.client.get('/enrolment/')
self.assertTemplateUsed(response, 'enrolment/index.html')
Thank you.
This is not standard Django authentication but one from django-allauth package.
To verify email address you have to create an EmailAdress object with verified=True
EmailAddress.objects.create(user=user, email="example#example.com", primary=True, verified=True)
You can see following model in source of django-allauth also some of package tests
Related
I am wondering if someone could help me. I am trying to test some views in a Django restaurant bookings system app I have created. I am doing well with jut testing the views but now I want to test the CRUD functionality of certain pages. In particular the create a booking on the bookings page and then redirect it back to the home page once the booking was successful (as is what happens on the site)
I just can't seem to figure out how to do it. Here is my current code. If someone could point me in the right direction that would be great. Thanks
setUp:
class TestViews(TestCase):
"""
Testing of the views taken from
the views.py file.
All HTTP testing includes the base.html template
as well as the view being tested to make sure everything
is being tested as it would appear for a user
"""
def setUp(self):
testing_user = User.objects.create_user(
username='JohnSmith',
first_name='John',
last_name='Smith',
email='johnsmith#email.com',
password='RandomWord1'
)
Booking.objects.create(
user=testing_user,
name='John Smith',
email_address='johnsmith#email.com',
phone='123654789',
number_of_people='2',
date='2022-10-20',
time='19:00',
table='Window',
occasion='none'
)
test:
def test_add_booking(self):
self.log_in()
response = self.client.post('/bookings', {Booking: Booking})
self.assertRedirects(response, '/')
You can check the status's code of your response, then also compare the response content.
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No bookins.")
Or even to be more precisely self.assertQuerysetEqual(response.context["the name"], ["with real content"]
My site runs multiple domains. Users can register on each of these domains. As a result, I need to make django-registration-redux:
use the correct email address for sending registration/password reset emails
use the correct email password for sending registration/password reset emails
use the correct domain within registration/password reset emails
I've been digging into the source code for django-registration-redux and believe that I need to update the send_email method within registration/models.py (https://github.com/macropin/django-registration/blob/master/registration/models.py) with my required changes.
I'm assuming the best way to add this cusomtization is as follows:
run 'pip uninstall django-registration-redux==2.2'
run 'pip freeze > requirements.txt'
from the source code, pull the 'registration' folder into my project
go into myproject/registration/models.py and manually update the send_email method so that it includes my changes.
Is there an easier or more correct way to build my custom logic into def send_email without making the changes noted above?
Thanks!
You could subclass the model then override the function that calls send_email() and patch it with your custom function.
from unittest import mock
from django_registration import models
def custom_send_email():
print('sending custom email')
class CustomEmailRegistration(models.Registration):
def function_calling_send_email(self):
with mock.patch('models.send_email', side_effect=custom_send_email):
super().function_calling_send_email()
Solution is to add a context processor that grabs the company name and website based on the current website, which can be accessed via request, and then reference the context variable within the django-registration email templates :)
This is how you add a context processor that gets the current hostname from the request:
Add a file my_ctx_proc.py to your application myapp:
def get_info_email(request):
return {
'info_email': "info#" + request.META['HTTP_HOST'],
}
In your settings.py, add in TEMPLATES OPTIONS context_processors at the end:
'myapp.my_ctx_proc.get_info_email',
Now you can insert {{ info_email }} in your email template, eg. templates/django_registration/activation_body_email.txt
I've enabled login authentication for my django app. Unit tests for views are not working because they get stuck at the login page. Setting a breakpoint immediately after the view's response is returned and using
print response.content
results in output that contains the phrase 'please login'
How do I setup a user so the testcase can login? I've tried using my username and password, but it doesn't work in the unit test context.
The following code inserted at the beginning of the testcase creates a user, logs them in, and allows the rest of the test to contiue
self.user = User.objects.create_user(username='testuser', password='12345')
login = self.client.login(username='testuser', password='12345')
I am working on a Django 1.4 project and writing one simple application using per-site cache as described here:
https://docs.djangoproject.com/en/dev/topics/cache/#the-per-site-cache
I have correctly setup a local Memcached server and confirmed the pages are being cached.
Then I set CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True because I don't want to cache pages for authenticated users.
I'm testing with a simple view that returns a template with render_to_response and RequestContext to be able to access user information from the template and the caching works well so far, meaning it caches pages just for anonymous users.
And here's my problem. I created another view using a different template that doesn't access user information and noticed that the page was being cached even if the user was authenticated. After testing many things I found that authenticated users were getting a cached page if the template didn't print something from the user context variable. It's very simple to test: print the user on the template and the page won't be cached for an authenticated user, remove the user on the template, refresh the page while authenticated and check the HTTP headers and you will notice you're getting a cached page. You should clear the cache between changes to see the problem more clearly.
I tested a little more and found that I could get rid of the user in the template and print request.user right on the view (which prints to the development server console) and that also fixed the problem of showing a cached page to an authenticated user but that's an ugly hack.
A similar problem was reported here but never got an answer:
https://groups.google.com/d/topic/django-users/FyWmz9csy5g/discussion
I can probably write a conditional decorator to check if user.is_authenticated() and based on that use #never_cache on my view but it seems like that defeats the purpose of using per-site cache, doesn't it?
"""
A decorator to bypass per-site cache if the user is authenticated. Based on django.views.decorators.cache.never_cache.
See: http://stackoverflow.com/questions/12060036/why-django-1-4-per-site-cache-does-not-work-correctly-with-cache-middleware-anon
"""
from django.utils.decorators import available_attrs
from django.utils.cache import add_never_cache_headers
from functools import wraps
def conditional_cache(view_func):
"""
Checks the user and if it's authenticated pass it through never_cache.
This version uses functools.wraps for the wrapper function.
"""
#wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view_func(request, *args, **kwargs):
response = view_func(request, *args, **kwargs)
if request.user.is_authenticated():
add_never_cache_headers(response)
return response
return _wrapped_view_func
Any suggestions to avoid the need of an extra decorator will be appreciated.
Thanks!
Ok, I just confirmed my "problem" was caused by Django lazy loading the User object.
To confirm it, I just added something like this to my view:
test_var = "some text" + request.user
And I got an error message telling me I couldn't concatenate an str to a SimpleLazyObject. At this point the lazy loading logic hasn't got a real User object yet.
To bypass the lazy loading, hence return a non-cache view for authenticated users, I just needed to access some method or attribute to triggers an actual query on the User object. I ended up with this, which I think it's the simplest way:
bypass_lazyload = request.user.is_authenticated()
My conditional_cache decorator is no longer needed, although it was an interesting exercise.
I may not need to do this when I finish working with my views as I'll access some user methods and attributes on my templates anyway but it's good to know what was going on.
Regards.
I have a django server app that communicates with a gwt front-end using JSON. I want to introduce user authentication to the app and have started to incorporate the framework provided by django. At this point I have set up the server to respond with the user authentication form when necessary (using the #login_required decorator scheme described in the above link), but I'm not sure what to do with this in GWT.
If you are using GWT with django and have implemented user auth, it would be great to hear how you set things up.
Thanks.
The autotest project used gwt and django combination. Have a look at http://autotest.kernel.org/browser/trunk/frontend source code. To be specific I would modify http://autotest.kernel.org/browser/trunk/frontend/afe/json_rpc/serviceHandler.py and add something like below (which would filter login, logout and is__logged__in and for all other functions it would invoke request.user.is_authenticated() to make sure that all other json rpc are protected)
def invokeServiceEndpoint(self, meth, request, response, args):
if meth.func_name == "login" or meth.func_name == "logout" or meth.func_name == "is_loggedin":
return meth(request, *args)
else:
if request.user.is_authenticated():
return meth(request.user, *args)
else:
from studio.rpc_exceptions import AccessDeniedException
raise AccessDeniedException()
I never used Django, but you probably can set what will be returned when login is required.
You can, for instance, return a message so the client can prompt the user with the authentication form. Of course, you would need to account for this situation in every call, but then you could create a abstract request class to do this.