Emile
Emile

Reputation: 3474

Accessing Middleware value for testing a Django DetailView

I am writing a test for a DetailView that queries get_object() by accessing a value set in a Middleware. This is for a Companies application and Company Model. Each user is in a Company.

To access the company throughout the project, I set the current user's Company.uuid on the request via a custom middleware.

Middleware

from django.utils.deprecation import MiddlewareMixin

class DynamicCompanyUUIDMiddleware(MiddlewareMixin):
    """ Adds the current organization's UUID from the current user."""

    def process_request(self, request):
        try:
            company_uuid = request.user.company_uuid
        except:
            company_uuid = None
        request.company_uuid = company_uuid

That is used in the CompanyDetailView's get_object() method via a Mixin that I use for the other Company Views.

Mixin

class CompanyMixin(LoginRequiredMixin, SetHeadlineMixin):
    model = Company

    def get_object(self):
        return get_object_or_404(
            self.model,
            uuid=self.request.user.company_uuid)

Test

The test that I'm trying to write is:

from django.test import RequestFactory
from django.urls import reverse, resolve
from test_plus.test import TestCase
from ..models import Company
from ..views import CompanyDetailView

class BaseCompanyTestCase(TestCase):

    def setUp(self):
        self.user = self.make_user()
        self.object = Company.objects.create(owner=self.user, name="testcompany")
        self.user.company_uuid = self.object.uuid
        self.factory = RequestFactory()

class TestCompanyDetailView(BaseCompanyTestCase):

    def setUp(self):
        super(TestCompanyDetailView, self).setUp()
        self.client.login(username="testuser", password="password")
        self.view = CompanyDetailView()
        self.view.object = self.object
        request = self.factory.get(reverse('companies:detail'))
        request.user = self.user
        request.company_uuid = self.user.company_uuid
        response = CompanyDetailView.as_view()(request)
        self.assertEqual(response.status_code, 200)

    def test_get_headline(self):
        self.assertEqual(
            self.view.get_headline(),
            '%s Members' % self.object.name

Result

This results in a 404 with the testuser's company not being found.

Walking through it:

However I'm not returning the company as the 404 shows.

Question

Where am I going wrong on this? Thanks in advance for your help.

Answer

I was mixing Django's Client & RequestFactory. I have corrected the code above which is correct.

Upvotes: 3

Views: 437

Answers (1)

Emile
Emile

Reputation: 3474

I was mixing Django's Client & RequestFactory. After stepping away, I figured it out below -

from django.test import RequestFactory
from django.urls import reverse, resolve
from test_plus.test import TestCase
from ..models import Company
from ..views import CompanyDetailView

class BaseCompanyTestCase(TestCase):

    def setUp(self):
        self.user = self.make_user()
        self.object = Company.objects.create(owner=self.user, name="testcompany")
        self.user.company_uuid = self.object.uuid
        self.factory = RequestFactory()

class TestCompanyDetailView(BaseCompanyTestCase):

    def setUp(self):
        super(TestCompanyDetailView, self).setUp()
        self.client.login(username="testuser", password="password")
        self.view = CompanyDetailView()
        self.view.object = self.object
        request = self.factory.get(reverse('companies:detail'))
        request.user = self.user
        request.company_uuid = self.user.company_uuid
        response = CompanyDetailView.as_view()(request)
        self.assertEqual(response.status_code, 200)

    def test_get_headline(self):
        self.assertEqual(
            self.view.get_headline(),
            '%s Members' % self.object.name

Upvotes: 0

Related Questions