Is there a way to test blog post permissions in PyTest?
I've been trying to make the final test pass. I seem to be getting a 403 error, nothing that I'm not authorized to make a post. Even though I gave the test user authorization to post tests. I don't understand why it's still giving me the 403, even when I coded the authorization of the posts.
Here's the test proper:
@pytest.mark.django_db
def test_add_post_permission(self, test_client, test_user, contributor_group, add_post_permission):
add_post_url = reverse("posts:add_post")
post_list_url = reverse("posts:post_list")
#Test 1: Not logged in - Redirect to login
response_not_logged_in = test_client.get(add_post_url)
assert response_not_logged_in.status_code == 403 # Redirect to login
# Test 2: Logged in
logged_in = test_client.login(email=test_user.email, password="pass123")
assert logged_in
# Test 3: Logged in, but without permission
post_data = {"title": "CBV Post Title", "content": "CBV Post content"}
response_no_perm = test_client.post(add_post_url, post_data)
assert response_no_perm.status_code == 403
assert Post.objects.count() == 0
contributor_group.permissions.add(add_post_permission)
contributor_group.save()
# Assign user to the Contributor Group and give them permission to add posts
test_user.groups.add(contributor_group)
test_user.save()
test_user.get_all_permissions() # Ensure permissions are loaded
# Test 4: Test with permission
response_with_perm = test_client.post(add_post_url, post_data)
print(response_with_perm.status_code)
assert response_with_perm.status_code == 302
assert response_with_perm.url == post_list_url
assert Post.objects.count() == 1
# Test the post
new_post = Post.objects.first()
assert new_post.title == "CBV Post Title"
assert new_post.content == "CBV Post content"
assert new_post.author == test_user
Here's the URL:
urlpatterns = [
re_path(r'^posts/add_post/', AddPostView.as_view(), name="add_post"),
]
Here's the views.py:
class AddPostView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
model = Post
form_class = PostForm
template_name = 'posts/addpost.html'
fields = ['title', 'content']
permission_required = 'posts.add_post'
login_url = 'posts:homepage'
def handle_no_permission(self):
raise PermissionDenied("You do not have permission to add a post.")
def form_valid(self, form):
form.instance.author = self.request.user
messages.success(self.request, "Post created successfully!")
return super().form_valid(form)
If it helps, I also have the form class and the applicable view:
from django import forms
from .models import Post
from django.contrib.auth import get_user_model
class PostForm(forms.ModelForm):
title = forms.CharField(label="Title", max_length=150)
content = forms.CharField(widget=forms.Textarea)
User = get_user_model()
class Meta:
model = Post
fields = ('title', 'content')
{% extends 'base.html' %}
{% block title %} Create a Blog Post! {% endblock %}
{% block content %}
<h1>Create Post</h1>
<br/><br/>
<div class="form-group">
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-secondary">Post</button>
</form>
</div>
{% endblock %}
In addition, is there a logic to test permissions with PyTest? Thanks.