2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-30 04:26:44 +00:00

Merge pull request #1729 from SchrodingersGat/api-bug-fix

Adds unit tests for HTML API endpoints
This commit is contained in:
Oliver 2021-06-28 21:23:36 +10:00 committed by GitHub
commit ce731db203
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 98 additions and 11 deletions

View File

@ -7,8 +7,6 @@ from __future__ import unicode_literals
import os import os
from collections import OrderedDict
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError as DjangoValidationError from django.core.exceptions import ValidationError as DjangoValidationError
@ -46,14 +44,11 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
def __init__(self, instance=None, data=empty, **kwargs): def __init__(self, instance=None, data=empty, **kwargs):
self.instance = instance # self.instance = instance
# If instance is None, we are creating a new instance # If instance is None, we are creating a new instance
if instance is None: if instance is None and data is not empty:
if data is empty:
data = OrderedDict()
else:
# Required to side-step immutability of a QueryDict # Required to side-step immutability of a QueryDict
data = data.copy() data = data.copy()
@ -64,6 +59,11 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
for field_name, field in fields.fields.items(): for field_name, field in fields.fields.items():
"""
Update the field IF (and ONLY IF):
- The field has a specified default value
- The field does not already have a value set
"""
if field.has_default() and field_name not in data: if field.has_default() and field_name not in data:
value = field.default value = field.default
@ -85,7 +85,7 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
Use the 'default' values specified by the django model definition Use the 'default' values specified by the django model definition
""" """
initials = super().get_initial() initials = super().get_initial().copy()
# Are we creating a new instance? # Are we creating a new instance?
if self.instance is None: if self.instance is None:
@ -111,7 +111,8 @@ class InvenTreeModelSerializer(serializers.ModelSerializer):
return initials return initials
def run_validation(self, data=empty): def run_validation(self, data=empty):
""" Perform serializer validation. """
Perform serializer validation.
In addition to running validators on the serializer fields, In addition to running validators on the serializer fields,
this class ensures that the underlying model is also validated. this class ensures that the underlying model is also validated.
""" """

View File

@ -2,6 +2,11 @@
from rest_framework import status from rest_framework import status
from django.test import TestCase
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.urls import reverse from django.urls import reverse
from InvenTree.api_tester import InvenTreeAPITestCase from InvenTree.api_tester import InvenTreeAPITestCase
@ -11,6 +16,87 @@ from users.models import RuleSet
from base64 import b64encode from base64 import b64encode
class HTMLAPITests(TestCase):
"""
Test that we can access the REST API endpoints via the HTML interface.
History: Discovered on 2021-06-28 a bug in InvenTreeModelSerializer,
which raised an AssertionError when using the HTML API interface,
while the regular JSON interface continued to work as expected.
"""
def setUp(self):
super().setUp()
# Create a user
user = get_user_model()
self.user = user.objects.create_user(
username='username',
email='user@email.com',
password='password'
)
# Put the user into a group with the correct permissions
group = Group.objects.create(name='mygroup')
self.user.groups.add(group)
# Give the group *all* the permissions!
for rule in group.rule_sets.all():
rule.can_view = True
rule.can_change = True
rule.can_add = True
rule.can_delete = True
rule.save()
self.client.login(username='username', password='password')
def test_part_api(self):
url = reverse('api-part-list')
# Check JSON response
response = self.client.get(url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
# Check HTTP response
response = self.client.get(url, HTTP_ACCEPT='text/html')
self.assertEqual(response.status_code, 200)
def test_build_api(self):
url = reverse('api-build-list')
# Check JSON response
response = self.client.get(url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
# Check HTTP response
response = self.client.get(url, HTTP_ACCEPT='text/html')
self.assertEqual(response.status_code, 200)
def test_stock_api(self):
url = reverse('api-stock-list')
# Check JSON response
response = self.client.get(url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
# Check HTTP response
response = self.client.get(url, HTTP_ACCEPT='text/html')
self.assertEqual(response.status_code, 200)
def test_company_list(self):
url = reverse('api-company-list')
# Check JSON response
response = self.client.get(url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
# Check HTTP response
response = self.client.get(url, HTTP_ACCEPT='text/html')
self.assertEqual(response.status_code, 200)
class APITests(InvenTreeAPITestCase): class APITests(InvenTreeAPITestCase):
""" Tests for the InvenTree API """ """ Tests for the InvenTree API """