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.

It looks like you want to simulate different types of users (author, random user, anonymous) to confirm they either can or cannot perform certain actions (like update, delete) on a blog post. 

You'll need to follow this step-by-step: 

Setting up Fixtures for: 
 a) Author User 
 b) Other user 
 c) Anonymous client 
 d) A sample blog post. 

Write Permission Test Cases: 
def test_author_can_update_post(author_client, blog_post): 
    response = author_client.post(f'/blog/{blog_post.id}/edit/', { 
        'title': 'Updated', 
        'content': 'Updated content' 
    }) 
    assert response.status_code == 302  # assuming redirect on success 
    blog_post.refresh_from_db() 
    assert blog_post.title == 'Updated' 

  

def test_other_user_cannot_update_post(other_client, blog_post): 
    response = other_client.post(f'/blog/{blog_post.id}/edit/', { 
        'title': 'Hacked!', 
        'content': 'Bad content' 
    }) 
    assert response.status_code == 403  # Forbidden (or 302 if redirected to login) 

  

def test_anonymous_user_cannot_update_post(client, blog_post): 
    response = client.post(f'/blog/{blog_post.id}/edit/', { 
        'title': 'Anonymous edit', 
        'content': 'Not allowed' 
    }) 
    assert response.status_code in (302, 403) 
 
 

Please refer to the following link for updated documentation: RequestFactory Docs 
Вернуться на верх