2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-18 21:15:41 +00:00

Add tests for report API (#6214)

* Add tests for report api

* Add test for delete endpoint

* Use pk in reverse call

* Allow kwargs in APITestCase methods

* Data is in response.data

* Fix comment

* Use expected_code argument instead of separate check

* Test with superuser

* Negative indexing not allowed, try with this alternative

* Looking for what went wrong..

* APITestCase does not work like Python requests - change POST calls

* Upload success is code 201

* In PATCH method, change test file and description as well

* Add test for get_api_url method

* Change format parameter for file upload

* Copy tests for report API over to label API

* Add test model for BuildLineLabel

* Update tests

* Make example template valid

* Add methods for testing label printing
This commit is contained in:
miggland
2024-01-16 20:55:55 +01:00
committed by GitHub
parent 21ff17332d
commit 5c7d3af150
3 changed files with 411 additions and 35 deletions

View File

@ -1,43 +1,306 @@
"""Unit tests for label API."""
import json
from io import StringIO
from django.core.cache import cache
from django.urls import reverse
import label.models as label_models
from build.models import BuildLine
from InvenTree.unit_test import InvenTreeAPITestCase
from part.models import Part
from stock.models import StockItem, StockLocation
class TestReportTests(InvenTreeAPITestCase):
"""Tests for the StockItem TestReport templates."""
class LabelTest(InvenTreeAPITestCase):
"""Base class for unit testing label model API endpoints."""
fixtures = ['category', 'part', 'location', 'stock']
fixtures = ['category', 'part', 'location', 'stock', 'bom', 'build']
roles = ['stock.view', 'stock_location.view']
superuser = True
list_url = reverse('api-stockitem-testreport-list')
model = None
list_url = None
detail_url = None
metadata_url = None
def do_list(self, filters=None):
"""Helper function to request list of labels with provided filters."""
# Set default - see B006
if filters is None:
filters = {}
print_url = None
print_itemname = None
print_itemmodel = None
response = self.client.get(self.list_url, filters, format='json')
def setUp(self):
"""Ensure cache is cleared as part of test setup."""
cache.clear()
return super().setUp()
def test_api_url(self):
"""Test returned API Url against URL tag defined in this file."""
if not self.list_url:
return
self.assertEqual(reverse(self.list_url), self.model.get_api_url())
def test_list_endpoint(self):
"""Test that the LIST endpoint works for each model."""
if not self.list_url:
return
url = reverse(self.list_url)
response = self.get(url)
self.assertEqual(response.status_code, 200)
return response.data
labels = self.model.objects.all()
n = len(labels)
def test_list(self):
"""Test the API list endpoint."""
response = self.do_list()
# API endpoint must return correct number of reports
self.assertEqual(len(response.data), n)
# TODO - Add some report templates to the fixtures
self.assertEqual(len(response), 0)
# Filter by "enabled" status
response = self.get(url, {'enabled': True})
self.assertEqual(len(response.data), n)
# TODO - Add some tests to this response
response = self.do_list({'item': 10})
response = self.get(url, {'enabled': False})
self.assertEqual(len(response.data), 0)
# TODO - Add some tests to this response
response = self.do_list({'item': 100000})
# Disable each report
for label in labels:
label.enabled = False
label.save()
# TODO - Add some tests to this response
response = self.do_list({'items': [10, 11, 12]})
# Filter by "enabled" status
response = self.get(url, {'enabled': True})
self.assertEqual(len(response.data), 0)
response = self.get(url, {'enabled': False})
self.assertEqual(len(response.data), n)
def test_create_endpoint(self):
"""Test that creating a new report works for each label."""
if not self.list_url:
return
url = reverse(self.list_url)
# Create a new label
# Django REST API "APITestCase" does not work like requests - to send a file without it existing on disk,
# create it as a StringIO object, and upload it under parameter template
filestr = StringIO(
'{% extends "label/label_base.html" %}{% block content %}<pre>TEST LABEL</pre>{% endblock content %}'
)
filestr.name = 'ExampleTemplate.html'
response = self.post(
url,
data={
'name': 'New label',
'description': 'A fancy new label created through API test',
'label': filestr,
},
format=None,
expected_code=201,
)
# Make sure the expected keys are in the response
self.assertIn('pk', response.data)
self.assertIn('name', response.data)
self.assertIn('description', response.data)
self.assertIn('label', response.data)
self.assertIn('filters', response.data)
self.assertIn('enabled', response.data)
self.assertEqual(response.data['name'], 'New label')
self.assertEqual(
response.data['description'], 'A fancy new label created through API test'
)
self.assertEqual(response.data['label'].count('ExampleTemplate'), 1)
def test_detail_endpoint(self):
"""Test that the DETAIL endpoint works for each label."""
if not self.detail_url:
return
# Create an item first
self.test_create_endpoint()
labels = self.model.objects.all()
n = len(labels)
# Make sure at least one report defined
self.assertGreaterEqual(n, 1)
# Check detail page for first report
response = self.get(
reverse(self.detail_url, kwargs={'pk': labels[0].pk}), expected_code=200
)
# Make sure the expected keys are in the response
self.assertIn('pk', response.data)
self.assertIn('name', response.data)
self.assertIn('description', response.data)
self.assertIn('label', response.data)
self.assertIn('filters', response.data)
self.assertIn('enabled', response.data)
filestr = StringIO(
'{% extends "label/label_base.html" %}{% block content %}<pre>TEST LABEL</pre>{% endblock content %}'
)
filestr.name = 'ExampleTemplate_Updated.html'
# Check PATCH method
response = self.patch(
reverse(self.detail_url, kwargs={'pk': labels[0].pk}),
{
'name': 'Changed name during test',
'description': 'New version of the template',
'label': filestr,
},
format=None,
expected_code=200,
)
# Make sure the expected keys are in the response
self.assertIn('pk', response.data)
self.assertIn('name', response.data)
self.assertIn('description', response.data)
self.assertIn('label', response.data)
self.assertIn('filters', response.data)
self.assertIn('enabled', response.data)
self.assertEqual(response.data['name'], 'Changed name during test')
self.assertEqual(response.data['description'], 'New version of the template')
self.assertEqual(response.data['label'].count('ExampleTemplate_Updated'), 1)
def test_delete(self):
"""Test deleting, after other test are done."""
if not self.detail_url:
return
# Create an item first
self.test_create_endpoint()
labels = self.model.objects.all()
n = len(labels)
# Make sure at least one label defined
self.assertGreaterEqual(n, 1)
# Delete the last report
response = self.delete(
reverse(self.detail_url, kwargs={'pk': labels[n - 1].pk}), expected_code=204
)
def test_print_label(self):
"""Test printing a label."""
if not self.print_url:
return
# Create an item first
self.test_create_endpoint()
labels = self.model.objects.all()
n = len(labels)
# Make sure at least one label defined
self.assertGreaterEqual(n, 1)
url = reverse(self.print_url, kwargs={'pk': labels[0].pk})
# Try to print without providing a valid item
response = self.get(url, expected_code=400)
# Try to print with an invalid item
response = self.get(url, {self.print_itemname: 9999}, expected_code=400)
# Now print with a valid item
print(f'{self.print_itemmodel = }')
print(f'{self.print_itemmodel.objects.all() = }')
item = self.print_itemmodel.objects.first()
self.assertIsNotNone(item)
response = self.get(url, {self.print_itemname: item.pk}, expected_code=200)
response_json = json.loads(response.content.decode('utf-8'))
self.assertIn('file', response_json)
self.assertIn('success', response_json)
self.assertIn('message', response_json)
self.assertTrue(response_json['success'])
def test_metadata_endpoint(self):
"""Unit tests for the metadata field."""
if not self.metadata_url:
return
# Create an item first
self.test_create_endpoint()
labels = self.model.objects.all()
n = len(labels)
# Make sure at least one label defined
self.assertGreaterEqual(n, 1)
# Test getting metadata
response = self.get(
reverse(self.metadata_url, kwargs={'pk': labels[0].pk}), expected_code=200
)
self.assertEqual(response.data, {'metadata': {}})
class TestStockItemLabel(LabelTest):
"""Unit testing class for the StockItemLabel model."""
model = label_models.StockItemLabel
list_url = 'api-stockitem-label-list'
detail_url = 'api-stockitem-label-detail'
metadata_url = 'api-stockitem-label-metadata'
print_url = 'api-stockitem-label-print'
print_itemname = 'item'
print_itemmodel = StockItem
class TestStockLocationLabel(LabelTest):
"""Unit testing class for the StockLocationLabel model."""
model = label_models.StockLocationLabel
list_url = 'api-stocklocation-label-list'
detail_url = 'api-stocklocation-label-detail'
metadata_url = 'api-stocklocation-label-metadata'
print_url = 'api-stocklocation-label-print'
print_itemname = 'location'
print_itemmodel = StockLocation
class TestPartLabel(LabelTest):
"""Unit testing class for the PartLabel model."""
model = label_models.PartLabel
list_url = 'api-part-label-list'
detail_url = 'api-part-label-detail'
metadata_url = 'api-part-label-metadata'
print_url = 'api-part-label-print'
print_itemname = 'part'
print_itemmodel = Part
class TestBuildLineLabel(LabelTest):
"""Unit testing class for the BuildLine model."""
model = label_models.BuildLineLabel
list_url = 'api-buildline-label-list'
detail_url = 'api-buildline-label-detail'
metadata_url = 'api-buildline-label-metadata'
print_url = 'api-buildline-label-print'
print_itemname = 'line'
print_itemmodel = BuildLine