mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
* Squashed commit of the following: commit52d7ff0f65
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 23:03:20 2024 +0100 fixed lookup commit0d076eaea8
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 23:03:08 2024 +0100 switched to pathlib for lookup commit473e75eda2
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 22:52:30 2024 +0100 fix wrong url response commitfd74f8d703
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 21:14:38 2024 +0100 switched to ruff for import sorting commitf83fedbbb8
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 21:03:14 2024 +0100 switched to single quotes everywhere commita92442e60e
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:58:23 2024 +0100 added autofixes commitcc66c93136
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:56:47 2024 +0100 enable autoformat commit1f343606ec
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:42:14 2024 +0100 Squashed commit of the following: commitf5cf7b2e78
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:36:57 2024 +0100 fixed reqs commit9d845bee98
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:32:35 2024 +0100 disable autofix/format commitaff5f27148
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:28:50 2024 +0100 adjust checks commit47271cf1ef
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:28:22 2024 +0100 reorder order of operations commite1bf178b40
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:01:09 2024 +0100 adapted ruff settings to better fit code base commitad7d88a6f4
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 19:59:45 2024 +0100 auto fixed docstring commita2e54a760e
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 19:46:35 2024 +0100 fix getattr useage commitcb80c73bc6
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 19:25:09 2024 +0100 fix requirements file commitb7780bbd21
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:42:28 2024 +0100 fix removed sections commit71f1681f55
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:41:21 2024 +0100 fix djlint syntax commita0bcf1bcce
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:35:28 2024 +0100 remove flake8 from code base commit22475b31cc
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:34:56 2024 +0100 remove flake8 from code base commit0413350f14
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:24:39 2024 +0100 moved ruff section commitd90c48a0bf
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:24:24 2024 +0100 move djlint config to pyproject commitc5ce55d511
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:20:39 2024 +0100 added isort again commit42a41d23af
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:19:02 2024 +0100 move config section commit8569233181
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:17:52 2024 +0100 fix codespell error commit2897c6704d
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 17:29:21 2024 +0100 replaced flake8 with ruff mostly for speed improvements * enable docstring checks * fix docstrings * fixed D417 Missing argument description * Squashed commit of the following: commitd3b795824b
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 22:56:17 2024 +0100 fixed source path commit0bac0c19b8
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 22:47:53 2024 +0100 fixed req commit9f61f01d9c
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 22:45:18 2024 +0100 added missing toml req commit91b71ed24a
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:49:50 2024 +0100 moved isort config commit12460b0419
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:43:22 2024 +0100 remove flake8 section from setup.cfg commitf5cf7b2e78
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:36:57 2024 +0100 fixed reqs commit9d845bee98
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:32:35 2024 +0100 disable autofix/format commitaff5f27148
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:28:50 2024 +0100 adjust checks commit47271cf1ef
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:28:22 2024 +0100 reorder order of operations commite1bf178b40
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 20:01:09 2024 +0100 adapted ruff settings to better fit code base commitad7d88a6f4
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 19:59:45 2024 +0100 auto fixed docstring commita2e54a760e
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 19:46:35 2024 +0100 fix getattr useage commitcb80c73bc6
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 19:25:09 2024 +0100 fix requirements file commitb7780bbd21
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:42:28 2024 +0100 fix removed sections commit71f1681f55
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:41:21 2024 +0100 fix djlint syntax commita0bcf1bcce
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:35:28 2024 +0100 remove flake8 from code base commit22475b31cc
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:34:56 2024 +0100 remove flake8 from code base commit0413350f14
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:24:39 2024 +0100 moved ruff section commitd90c48a0bf
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:24:24 2024 +0100 move djlint config to pyproject commitc5ce55d511
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:20:39 2024 +0100 added isort again commit42a41d23af
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:19:02 2024 +0100 move config section commit8569233181
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 18:17:52 2024 +0100 fix codespell error commit2897c6704d
Author: Matthias Mair <code@mjmair.com> Date: Sun Jan 7 17:29:21 2024 +0100 replaced flake8 with ruff mostly for speed improvements * fix pyproject * make docstrings more uniform * auto-format * fix order * revert url change
166 lines
5.5 KiB
Python
166 lines
5.5 KiB
Python
"""Tests for labels."""
|
|
|
|
import io
|
|
import json
|
|
|
|
from django.apps import apps
|
|
from django.conf import settings
|
|
from django.core.exceptions import ValidationError
|
|
from django.core.files.base import ContentFile
|
|
from django.http import JsonResponse
|
|
from django.urls import reverse
|
|
|
|
from common.models import InvenTreeSetting
|
|
from InvenTree.helpers import validateFilterString
|
|
from InvenTree.unit_test import InvenTreeAPITestCase
|
|
from label.models import LabelOutput
|
|
from part.models import Part
|
|
from plugin.registry import registry
|
|
from stock.models import StockItem
|
|
|
|
from .models import PartLabel, StockItemLabel, StockLocationLabel
|
|
|
|
|
|
class LabelTest(InvenTreeAPITestCase):
|
|
"""Unit test class for label models."""
|
|
|
|
fixtures = ['category', 'part', 'location', 'stock']
|
|
|
|
@classmethod
|
|
def setUpTestData(cls):
|
|
"""Ensure that some label instances exist as part of init routine."""
|
|
super().setUpTestData()
|
|
apps.get_app_config('label').create_labels()
|
|
|
|
def test_default_labels(self):
|
|
"""Test that the default label templates are copied across."""
|
|
labels = StockItemLabel.objects.all()
|
|
|
|
self.assertTrue(labels.count() > 0)
|
|
|
|
labels = StockLocationLabel.objects.all()
|
|
|
|
self.assertTrue(labels.count() > 0)
|
|
|
|
def test_default_files(self):
|
|
"""Test that label files exist in the MEDIA directory."""
|
|
|
|
def test_subdir(ref_name):
|
|
item_dir = settings.MEDIA_ROOT.joinpath('label', 'inventree', ref_name)
|
|
self.assertTrue(len([item_dir.iterdir()]) > 0)
|
|
|
|
test_subdir('stockitem')
|
|
test_subdir('stocklocation')
|
|
test_subdir('part')
|
|
|
|
def test_filters(self):
|
|
"""Test the label filters."""
|
|
filter_string = 'part__pk=10'
|
|
|
|
filters = validateFilterString(filter_string, model=StockItem)
|
|
|
|
self.assertEqual(type(filters), dict)
|
|
|
|
bad_filter_string = 'part_pk=10'
|
|
|
|
with self.assertRaises(ValidationError):
|
|
validateFilterString(bad_filter_string, model=StockItem)
|
|
|
|
def test_label_rendering(self):
|
|
"""Test label rendering."""
|
|
labels = PartLabel.objects.all()
|
|
part = Part.objects.first()
|
|
|
|
for label in labels:
|
|
url = reverse('api-part-label-print', kwargs={'pk': label.pk})
|
|
|
|
# Check that label printing returns the correct response type
|
|
response = self.get(f'{url}?parts={part.pk}', expected_code=200)
|
|
self.assertIsInstance(response, JsonResponse)
|
|
data = json.loads(response.content)
|
|
|
|
self.assertIn('message', data)
|
|
self.assertIn('file', data)
|
|
label_file = data['file']
|
|
self.assertIn('/media/label/output/', label_file)
|
|
|
|
def test_print_part_label(self):
|
|
"""Actually 'print' a label, and ensure that the correct information is contained."""
|
|
label_data = """
|
|
{% load barcode %}
|
|
{% load report %}
|
|
|
|
<html>
|
|
<!-- Test that the part instance is supplied -->
|
|
part: {{ part.pk }} - {{ part.name }}
|
|
<!-- Test qr data -->
|
|
data: {{ qr_data|safe }}
|
|
<!-- Test InvenTree URL -->
|
|
url: {{ qr_url|safe }}
|
|
<!-- Test image URL generation -->
|
|
image: {% part_image part width=128 %}
|
|
<!-- Test InvenTree logo -->
|
|
logo: {% logo_image %}
|
|
</html>
|
|
"""
|
|
|
|
buffer = io.StringIO()
|
|
buffer.write(label_data)
|
|
|
|
template = ContentFile(buffer.getvalue(), 'label.html')
|
|
|
|
# Construct a label template
|
|
label = PartLabel.objects.create(
|
|
name='test', description='Test label', enabled=True, label=template
|
|
)
|
|
|
|
# Ensure we are in "debug" mode (so the report is generated as HTML)
|
|
InvenTreeSetting.set_setting('REPORT_ENABLE', True, None)
|
|
|
|
# Set the 'debug' setting for the plugin
|
|
plugin = registry.get_plugin('inventreelabel')
|
|
plugin.set_setting('DEBUG', True)
|
|
|
|
# Print via the API (Note: will default to the builtin plugin if no plugin supplied)
|
|
url = reverse('api-part-label-print', kwargs={'pk': label.pk})
|
|
|
|
prt = Part.objects.first()
|
|
part_pk = prt.pk
|
|
part_name = prt.name
|
|
|
|
response = self.get(f'{url}?parts={part_pk}', expected_code=200)
|
|
data = json.loads(response.content)
|
|
self.assertIn('file', data)
|
|
|
|
# Find the generated file
|
|
output = LabelOutput.objects.last()
|
|
|
|
# Open the file and read data
|
|
with open(output.label.path, 'r') as f:
|
|
content = f.read()
|
|
|
|
# Test that each element has been rendered correctly
|
|
self.assertIn(f'part: {part_pk} - {part_name}', content)
|
|
self.assertIn(f'data: {{"part": {part_pk}}}', content)
|
|
self.assertIn(f'http://testserver/part/{part_pk}/', content)
|
|
|
|
# Check that a encoded image has been generated
|
|
self.assertIn('data:image/png;charset=utf-8;base64,', content)
|
|
|
|
def test_metadata(self):
|
|
"""Unit tests for the metadata field."""
|
|
for model in [StockItemLabel, StockLocationLabel, PartLabel]:
|
|
p = model.objects.first()
|
|
|
|
self.assertIsNone(p.get_metadata('test'))
|
|
self.assertEqual(p.get_metadata('test', backup_value=123), 123)
|
|
|
|
# Test update via the set_metadata() method
|
|
p.set_metadata('test', 3)
|
|
self.assertEqual(p.get_metadata('test'), 3)
|
|
|
|
for k in ['apple', 'banana', 'carrot', 'carrot', 'banana']:
|
|
p.set_metadata(k, k)
|
|
|
|
self.assertEqual(len(p.metadata.keys()), 4)
|