mercredi 6 janvier 2021

Test case for a Django view

I need help in understanding how to write a particular test case for a view and I can not get my head around it. I am basically using the polls app in Django docs example but I have extended it quite a bit.

I have a view called createQuestion that renders createQuestion.html. The user can add a question and can add a minimum of 1 and a max of 10 choices to each question. If the user tries to submit with completing the requirements an error will be shown and the form won't submit till at-least one choice is added or if the user tries to add more than 10 choices. I also check the number of choices submitted in the backend as well, if more than 10 come or less than 1 come the createQuestion.html will render again giving the error message "Incorrect number of choices".

What I need help with

I don't understand how I can write a test case for this view in tests.py to check if the page contains the error messages if the user tries to submit more than 10 or less than 1.

Code

Here is the code for models.py and view in views.py.

I have three models in models.py:

import datetime

from django.contrib.auth.models import User
from django.db import models
from django.utils import timezone


class AnonymousUser(models.Model):
    ip_address = models.GenericIPAddressField(null=True)

    def __str__(self):
        return "Anonymous User IP: " + str(self.ip_address)


class Question(models.Model):
    user = models.ForeignKey(AnonymousUser, on_delete=models.CASCADE, null=True)  # one to one
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField("date published")

    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now

    was_published_recently.admin_order_field = "pub_date"
    was_published_recently.boolean = True
    was_published_recently.short_description = "Published recently?"


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

createQuestion view in views.py:

def createQuestion(request):
    if request.method == "GET":
        return render(request, "polls/createQuestion.html")
    else:
        """
        POST request user.
        """

        choices = [value for key, value in request.POST.items() if "choice" in key]
        if len(choices) < 1 or len(choices) > 10:
            return render(
                request,
                "polls/createQuestion.html",
                {"error": "Incorrect number of choices"},
            )

        try:
            if not AnonymousUser.objects.filter(ip_address=get_ip_address(request)):
                user = AnonymousUser(ip_address=get_ip_address(request))
                user.save()
            else:
                user = AnonymousUser.objects.filter(ip_address=get_ip_address(request))[
                    0
                ]

            question = Question(
                user=user,  # storing anonymous user as foreign key
                question_text=request.POST["question_text"],  # storing question
                pub_date=request.POST["datetime"],  # saving publishing date
            )
            question.save()

            """
            saving choices and question id
            """
            for choice in choices:
                choice_text = choice
                choice_object = Choice(question_id=question.id, choice_text=choice_text)
                choice_object.save()

            return redirect("polls:index")

        except Exception as e:
            print(e)
            """
            If there any error send redirect back with error message
            """
            return render(
                request, "polls/createQuestion.html", {"error": "Wrong input"}
            )

Aucun commentaire:

Enregistrer un commentaire