Skip to content

Commit

Permalink
Update unit tests for label printing
Browse files Browse the repository at this point in the history
  • Loading branch information
SchrodingersGat committed May 10, 2024
1 parent 2ce6a58 commit 03421ab
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 193 deletions.
29 changes: 23 additions & 6 deletions inventree/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,12 @@ def printLabelModern(self, template, plugin=None, destination=None, *args, **kwa

if plugin is not None:
# For the modern printing API, plugin is provided as a pk (integer) value
if type(plugin) is not int:
raise ValueError(f"Plugin ID must be an integer, not {type(plugin)}")
if type(plugin) is int:
plugin = int(plugin)
elif hasattr(plugin, 'pk'):
plugin = int(plugin.pk)
else:
raise ValueError(f"Invalid plugin provided: {type(plugin)}")

data['plugin'] = plugin

Expand All @@ -158,6 +162,8 @@ def getLabelTemplates(self, **kwargs):
logger.error("Legacy label printing API is not supported")
return []

print("getting templates for:", self.getModelType())

return LabelTemplate.list(
self._api,
model_type=self.getModelType(),
Expand All @@ -168,6 +174,15 @@ def getLabelTemplates(self, **kwargs):
class LabelFunctions(inventree.base.MetadataMixin, inventree.base.InventreeObject):
"""Base class for label functions."""

@property
def template_key(self):
"""Return the attribute name for the template file."""

if self._api.api_version < MODERN_LABEL_PRINTING_API:
return 'label'
else:
return 'template'

@classmethod
def create(cls, api, data, label, **kwargs):
"""Create a new label by uploading a label template file. Convenience wrapper around base create() method.
Expand All @@ -189,8 +204,10 @@ def create(cls, api, data, label, **kwargs):
if label.readable() is False:
raise ValueError("Label template file must be readable")

template_key = 'template' if api.api_version >= MODERN_LABEL_PRINTING_API else 'label'

try:
response = super().create(api, data=data, files={'label': label}, **kwargs)
response = super().create(api, data=data, files={template_key: label}, **kwargs)
finally:
if label is not None:
label.close()
Expand Down Expand Up @@ -219,9 +236,9 @@ def save(self, data=None, label=None, **kwargs):

if 'files' in kwargs:
files = kwargs.pop('kwargs')
files['label'] = label
files[self.template_key] = label
else:
files = {'label': label}
files = {self.template_key: label}
else:
files = None

Expand All @@ -236,7 +253,7 @@ def downloadTemplate(self, destination, overwrite=False):
"""Download template file for the label to the given destination"""

# Use downloadFile method to get the file
return self._api.downloadFile(url=self._data['label'], destination=destination, overwrite=overwrite)
return self._api.downloadFile(url=self._data[self.template_key], destination=destination, overwrite=overwrite)


class LabelLocation(LabelFunctions):
Expand Down
233 changes: 46 additions & 187 deletions test/test_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,208 +7,67 @@

from test_api import InvenTreeTestCase # noqa: E402

from inventree.label import LabelLocation, LabelPart, LabelStock # noqa: E402
from inventree.label import LabelTemplate # noqa: E402
from inventree.part import Part # noqa: E402
from inventree.stock import StockItem, StockLocation # noqa: E402
from inventree.plugin import InvenTreePlugin

class LabelTemplateTests(InvenTreeTestCase):
"""Unit tests for label templates and printing, using the modern API."""

class LabelTest(InvenTreeTestCase):
"""Tests for Label functions models"""
def test_label_template_list(self):
"""List available label templates."""

def test_label_list(self):
"""
Test for using listing functionality of each type of label
"""
n = LabelTemplate.count(self.api)
templates = LabelTemplate.list(self.api)

# Parts
# Get label list
lbl_part_list = LabelPart.list(self.api)
self.assertEqual(n, len(templates))
self.assertGreater(len(templates), 0)

# Make a new list filtered by LabelPart
# List should be non-zero length
# Filtered list should be equal the original list
lbl_part_list_filtered = [x for x in lbl_part_list if isinstance(x, LabelPart)]
# Check some expected attributes
for attr in ['name', 'description', 'enabled', 'model_type', 'template']:
for template in templates:
self.assertIn(attr, template)

self.assertGreater(len(lbl_part_list_filtered), 0)
self.assertEqual(lbl_part_list, lbl_part_list_filtered)
for idx, template in enumerate(templates):
enabled = idx > 0

# Stock Items
# Get label list
lbl_stock_list = LabelStock.list(self.api)
if template.enabled != enabled:
template.save(data = {'enabled': idx > 0})

# Make a new list filtered by LabelPart
# List should be non-zero length
# Filtered list should be equal the original list
lbl_stock_list_filtered = [x for x in lbl_stock_list if isinstance(x, LabelStock)]
# Filter by 'enabled' status
templates = LabelTemplate.list(self.api, enabled=True)
self.assertGreater(len(templates), 0)
self.assertLess(len(templates), n)

self.assertGreater(len(lbl_stock_list_filtered), 0)
self.assertEqual(lbl_stock_list, lbl_stock_list_filtered)
# Filter by 'disabled' status
templates = LabelTemplate.list(self.api, enabled=False)
self.assertGreater(len(templates), 0)
self.assertLess(len(templates), n)

# Stock Locations
# Get label list
lbl_location_list = LabelLocation.list(self.api)
def test_label_print(self):
"""Print a template!"""

# Make a new list filtered by LabelPart
# List should be non-zero length
# Filtered list should be equal the original list
lbl_location_list_filtered = [x for x in lbl_location_list if isinstance(x, LabelLocation)]
# Find a part to print
part = Part.list(self.api, limit=1)[0]

self.assertGreater(len(lbl_location_list_filtered), 0)
self.assertEqual(lbl_location_list, lbl_location_list_filtered)
templates = part.getLabelTemplates()
self.assertGreater(len(templates), 0)

def test_label_create_download(self):
"""
Tests creating a new label from API, by uploading the dummy template file
"""
template = templates[0]

def comparefiles(file1, file2):
"""Compare content of two files, return True if equal, else False"""
# Find an available plugin
plugins = InvenTreePlugin.list(self.api, active=True, mixin='labels')
self.assertGreater(len(plugins), 0)

F1 = open(file1, 'r')
contents_1 = F1.read()
F1.close()
plugin = plugins[0]

F2 = open(file2, 'r')
contents_2 = F2.read()
F2.close()
response = part.printLabel(label=template, plugin=plugin)

return contents_1 == contents_2

dummytemplate = os.path.join(os.path.dirname(__file__), 'dummytemplate.html')
dummytemplate2 = os.path.join(os.path.dirname(__file__), 'dummytemplate2.html')

for RepClass in (LabelPart, LabelStock, LabelLocation):
# Test for all Label classes sequentially

#
# Test with file name
#

# Create a new label based on the dummy template
newlabel = RepClass.create(
self.api,
{'name': 'Dummy label', 'description': 'Label created as test'},
dummytemplate
)

# The return value should be a LabelPart object
self.assertIsInstance(newlabel, RepClass)

# Try to download the template file
newlabel.downloadTemplate(destination="dummytemplate_download.html")

self.assertTrue(comparefiles("dummytemplate_download.html", dummytemplate))

# Remove the test file
os.remove("dummytemplate_download.html")

#
# Test with open(...)
#

# Create a new label based on the dummy template
with open(dummytemplate) as template_upload:
newlabel2 = RepClass.create(
self.api,
{'name': 'Dummy label', 'description': 'Label created as test'},
template_upload
)

# The return value should be a LabelPart object
self.assertIsInstance(newlabel2, RepClass)

# Try to download the template file
newlabel2.downloadTemplate(destination="dummytemplate_download.html")

self.assertTrue(comparefiles("dummytemplate_download.html", dummytemplate))

# Remove the test file
os.remove("dummytemplate_download.html")

#
# Test overwriting the label file with save method
# Use file name
#

newlabel2.save(data=None, label=dummytemplate2)

# Try to download the template file
newlabel2.downloadTemplate(destination="dummytemplate2_download.html")

self.assertTrue(comparefiles("dummytemplate2_download.html", dummytemplate2))
# Remove the test file
os.remove("dummytemplate2_download.html")

#
# Test overwriting the template file with save method
# Use open(...)
#

with open(dummytemplate) as template_upload:
newlabel2.save(data=None, label=template_upload)

# Try to download the template file
newlabel2.downloadTemplate(destination="dummytemplate_download.html")

self.assertTrue(comparefiles("dummytemplate_download.html", dummytemplate))

# Remove the test file
os.remove("dummytemplate_download.html")

def test_label_printing(self):
"""
Tests for using label printing function to download PDF files
"""

# For each class supporting printing, find a related object
# Define a file, write the label to this file
# Check for file

# Parts
# Object and label - get first in list
prt = Part.list(self.api)[0]
lbl_part = LabelPart.list(self.api)[0]

# Attempt to print to file - use label object
self.assertTrue(prt.printlabel(label=lbl_part, plugin=None, destination="partlabel_1.pdf"))

# Attempt to print to file - use label ID directly
self.assertTrue(prt.printlabel(label=lbl_part.pk, plugin=None, destination="partlabel_2.pdf"))

# Make sure the files exist
self.assertTrue(os.path.isfile("partlabel_1.pdf"))
self.assertTrue(os.path.isfile("partlabel_2.pdf"))
os.remove("partlabel_1.pdf")
os.remove("partlabel_2.pdf")

# StockItem
# Object and label - get first in list
sti = StockItem.list(self.api)[0]
lbl_sti = LabelStock.list(self.api)[0]

# Attempt to print to file - use label object
sti.printlabel(label=lbl_sti, plugin=None, destination="stocklabel_1.pdf")
# Attempt to print to file - use label ID directly
sti.printlabel(label=lbl_sti.pk, plugin=None, destination="stocklabel_2.pdf")

# Make sure the files exist
self.assertTrue(os.path.isfile("stocklabel_1.pdf"))
self.assertTrue(os.path.isfile("stocklabel_2.pdf"))
os.remove("stocklabel_1.pdf")
os.remove("stocklabel_2.pdf")

# StockLocation
# Object and label - get first in list
sloc = StockLocation.list(self.api)[0]
lbl_sloc = LabelLocation.list(self.api)[0]

# Attempt to print to file - use label object
sloc.printlabel(label=lbl_sloc, plugin=None, destination="locationlabel_1.pdf")
# Attempt to print to file - use label ID directly
sloc.printlabel(label=lbl_sloc.pk, plugin=None, destination="locationlabel_2.pdf")

# Make sure the files exist
self.assertTrue(os.path.isfile("locationlabel_1.pdf"))
self.assertTrue(os.path.isfile("locationlabel_2.pdf"))
os.remove("locationlabel_1.pdf")
os.remove("locationlabel_2.pdf")
for key in ['created', 'model_type', 'complete', 'output', 'template', 'plugin']:
self.assertIn(key, response)

self.assertEqual(response['complete'], True)
self.assertEqual(response['model_type'], 'part')
self.assertIsNotNone(response['output'])
self.assertEqual(response['template'], template.pk)
self.assertEqual(response['plugin'], plugin.key)

0 comments on commit 03421ab

Please sign in to comment.