Working on Hello Web App.
Please help with TestCase: test_edit_thing.
Here's the error details:
The error in case of '/things/django-book/edit/':
# AssertionError: No templates used to render the response
response = self.client.get('/things/django-book/edit/')
self.assertTemplateUsed(response, 'things/edit_thing.html')
The error in case of '/things/django-book/':
# AssertionError: Template 'things/edit_thing.html' was not a template used to render the response. Actual template(s) used: things/thing_detail.html, base.html
response = self.client.get('/things/django-book/')
self.assertTemplateUsed(response, 'things/edit_thing.html')
Code Snippet:
from django.contrib.auth.models import AnonymousUser, User
from django.test import TestCase, RequestFactory
from collection.models import Thing
from .views import *
class SimpleTest(TestCase):
def setUp(self):
# Every test needs access to the request factory.
self.factory = RequestFactory()
self.user = User.objects.create_user(username='Foo', password='barbaz')
self.thing = Thing.objects.create(name="Django Book",
description="Learn how to build your first Django web app.",
slug="django-book",
user=self.user)
def test_index(self):
request = self.factory.get('/index/')
response = index(request)
print(response.status_code)
self.assertEqual(response.status_code, 200)
response = self.client.get('/')
self.assertTemplateUsed(response, 'base.html')
def test_thing_detail(self):
django_book = Thing.objects.get(name="Django Book")
request = self.factory.get('/things/django-book/')
response = thing_detail(request, django_book.slug)
print(response.status_code)
self.assertEqual(response.status_code, 200)
response = self.client.get('/things/django-book/')
self.assertTemplateUsed(response, 'things/thing_detail.html')
def test_edit_thing(self):
django_book = Thing.objects.get(name="Django Book")
request = self.factory.get('/things/django-book/edit/')
request.user = django_book.user
response = edit_thing(request, django_book.slug)
print(response.status_code)
self.assertEqual(response.status_code, 200)
# AssertionError: No templates used to render the response
#response = self.client.get('/things/django-book/edit/')
# AssertionError: Template 'things/edit_thing.html' was not a template used to render the response. Actual template(s) used: things/thing_detail.html, base.html
#response = self.client.get('/things/django-book/')
#self.assertTemplateUsed(response, 'things/edit_thing.html')
# Right?
response = self.client.get('/things/django-book/')
self.assertTemplateUsed(response, 'things/thing_detail.html')
from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, redirect
from django.template.defaultfilters import slugify
from collection.forms import ThingForm
from collection.models import Thing
def index(request):
things = Thing.objects.all()
return render(request, 'index.html', {
'things': things,
})
def thing_detail(request, slug):
# grab the object...
thing = Thing.objects.get(slug=slug)
# and pass to the template
return render(request, 'things/thing_detail.html', {
'thing': thing,
})
@login_required
def edit_thing(request, slug):
# grab the object...
thing = Thing.objects.get(slug=slug)
# grab the current logged in user and make sure they're the owner of the thing
if thing.user != request.user:
raise Http404
# set the form we're using...
form_class = ThingForm
# if we're coming to this view from a submitted form,
if request.method == 'POST':
# grab the data from the submitted form
form = form_class(data=request.POST, instance=thing)
if form.is_valid():
# save the new data
form.save()
return redirect('thing_detail', slug=thing.slug)
# otherwise just create the form
else:
form = form_class(instance=thing)
# and render the template
return render(request, 'things/edit_thing.html', {
'thing': thing,
'form': form,
})
def create_thing(request):
form_class = ThingForm
# if we're coming from a submitted form, do this
if request.method == 'POST':
# grab the data from the submitted form and apply to the form
form = form_class(request.POST)
if form.is_valid():
# create an instance but do not save yet
thing = form.save(commit=False)
# set the additional details
thing.user = request.user
thing.slug = slugify(thing.name)
# save the object
thing.save()
# redirect to our newly created thing
return redirect('thing_detail', slug=thing.slug)
# otherwise just create the form
else:
form = form_class()
return render(request, 'things/create_thing.html', {
'form': form,
})
def browse_by_name(request, initial=None):
if initial:
things = Thing.objects.filter(
name__istartswith=initial).order_by('name')
else:
things = Thing.objects.all().order_by('name')
return render(request, 'search/search.html', {
'things': things,
'initial': initial,
})
Thanks
So the problem that you was having is that your user wasn't authenticated, and if user is not the same as user of the thing you raise Http404
It in your edit_thing
view
if thing.user != request.user:
raise Http404
So you needed to be authenticated. And that could be made with login
def test_edit_thing(self):
django_book = Thing.objects.get(name="Django Book")
request = self.factory.get('/things/django-book/edit/')
request.user = django_book.user
response = edit_thing(request, django_book.slug)
print(response.status_code)
self.assertEqual(response.status_code, 200)
self.client.login(username='Foo', password='barbaz')
response = self.client.get('/things/django-book/edit/')
self.assertTemplateUsed(response, 'things/edit_thing.html')