I'm doing some unit tests in this restaurant app, and the API request to cancel orders returns code 400 when running "manage.py test" command, but doing the same request on Postman works fine (with the server also running on my local machine with the "manage.py runserver" command). I think it's something I'm doing wrong with the unit test, but I'm not sure. In settings, Debug = True and ALLOWED_HOSTS = ['*'] (but I also tried ALLOWED_HOSTS = []). Here's the code:
tests.py
class CancelOrderAPITest(APITestCase):
def setUp(self):
test_product = Products.objects.create(id=1, name='testProduct', description='-test-', price=2.56)
test_product.save()
test_order = Order.objects.create(table=1, status='WA')
test_order.save()
test_order.product.add(test_product)
self.user = User.objects.create(username='test')
self.user.set_password('passtest')
self.user.save()
Payments.objects.create(value=0.0, user=self.user)
Token.objects.create(user=self.user)
def test_CancelWithCredentials(self):
check_login = self.client.login(username='test', password='passtest')
self.assertTrue(check_login)
token = Token.objects.get_or_create(user=self.user)
self.client.credentials(HTTP_AUTHORIZATION=f'Token {token[0].key}')
data = {"table": 1}
response = self.client.post(reverse('cancel-order'), data=data, content_type='application/json')
order = Order.objects.filter(table=data['table']).order_by('date')[0]
self.assertEqual(response.status_code, status.HTTP_200_OK) # returning 400. Investigate further
self.assertEqual(order.status, Order.Status.CANCELED)
views.py
class CancelOrder(APIView):
# REST API view for waiters to cancel orders. The waiter must be an authenticated user
permission_classes = (IsAuthenticated,)
parser_classes = (JSONParser,)
def post(self, request):
data = request.data
try:
order = Order.objects.filter(table=data['table']).order_by('date')[0]
order.status = Order.Status.CANCELED
order.save()
resp = {"status": "Order canceled!"}
except ObjectDoesNotExist:
resp = {"exception": "Couldn't find requested product!"}
return Response(resp)
models.py
class Order(models.Model):
class Status(models.TextChoices):
WAITING = 'WA', _('Waiting')
DELIVERED = 'DE', _('Delivered')
PARTIAL_DELIVER = 'PD', _('Partially Delivered')
PREPARING = 'PP', _('Preparing')
CANCELED = 'CA', _('Canceled')
PAID = 'PA', _('Paid')
product = models.ManyToManyField(Products)
table = models.IntegerField(default=1)
status = models.CharField(max_length=100, choices=Status.choices, default=Status.WAITING)
date = models.DateTimeField(default=datetime.datetime.now)
payment = models.ForeignKey(Payments, on_delete=models.DO_NOTHING, default=1)
CodePudding user response:
I figured it out, thanks to the @annonymous comment. For some reason the unit test was sending the data in the request with single quotes causing a parse error, even though I was declaring it with double quotes. Adding the following line before sending the request solved it:
data = json.dumps(data)