Search code examples
djangodjango-admindjango-admin-actions

Testing Django Admin Action (redirecting/auth issue)


I'm trying to write tests for an Admin action in the change_list view. I referred to this question but couldn't get the test to work. Here's my code and issue:

class StatusChangeTestCase(TestCase):
"""
Test case for batch changing 'status' to 'Show' or 'Hide'
"""

    def setUp(self):
        self.categories = factories.CategoryFactory.create_batch(5)

    def test_status_hide(self):
        """
        Test changing all Category instances to 'Hide'
        """
        # Set Queryset to be hidden
        to_be_hidden = models.Category.objects.values_list('pk', flat=True)
        # Set POST data to be passed to changelist url
        data = {
            'action': 'change_to_hide',
            '_selected_action': to_be_hidden
            }
        # Set change_url
        change_url = self.reverse('admin:product_category_changelist')
        # POST data to change_url
        response = self.post(change_url, data, follow=True)
        self.assertEqual(
            models.Category.objects.filter(status='show').count(), 0
           )

    def tearDown(self):
        models.Category.objects.all().delete()

I tried using print to see what the response was and this is what I got:

<HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/admin/login/?next=/admin/product/category/">

It seems like it needs my login credentials - I tried to create a user in setUp() and log in as per Django docs on testing but it didn't seem to work.

Any help would be appreciated!


Solution

  • I found the solution - I wasn't instantiating Django's Client() class when I created a superuser, so whenever I logged in - it didn't persist in my subsequent requests. The correct code should look like this.

    def test_status_hide(self):
    
        """
        Test changing all Category instances to 'Hide'
        """
    
        # Create user
        user = User.objects.create_superuser(
            username='new_user', email='[email protected]', password='password',
        )
    
        # Log in
        self.client = Client()
        self.client.login(username='new_user', password='password')
    
        # Set Queryset to be hidden
        to_be_hidden = models.Category.objects.values_list('pk', flat=True)
    
        # Set POST data to be passed to changelist url
        data = {
            'action': 'change_to_hide',
            '_selected_action': to_be_hidden
            }
    
        # Set change_url
        change_url = self.reverse('admin:product_category_changelist')
    
        # POST data to change_url
        response = self.client.post(change_url, data, follow=True)
        self.assertEqual(
            models.Category.objects.filter(status='show').count(), 0
            )