Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A bit more testing #8053

Merged
merged 45 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
fd4c163
add more admin testing
matmair Sep 1, 2024
d0be413
fix assertations
matmair Sep 1, 2024
c3db572
add test for importer admin
matmair Sep 1, 2024
88f9c70
Add tests for https://github.com/inventree/InvenTree/pull/7164
matmair Sep 1, 2024
80dd079
add common/attachment test
matmair Sep 1, 2024
4f1fbb2
Merge branch 'master' into app-stock-coverage
matmair Sep 15, 2024
938fc92
Merge branch 'master' into app-stock-coverage
matmair Sep 23, 2024
aafda07
Merge branch 'master' of https://github.com/inventree/InvenTree into …
matmair Sep 23, 2024
fdd4dc0
fix test
matmair Sep 23, 2024
db8f92c
add tests
matmair Sep 23, 2024
4cad8d1
remove unused definition - the view is read only
matmair Sep 23, 2024
62eba77
Revert "remove unused definition - the view is read only"
matmair Sep 24, 2024
2d1b0fc
more tests in report
matmair Sep 24, 2024
194e15b
Update tests.py
matmair Sep 24, 2024
3999e90
make lookup dynamic
matmair Sep 25, 2024
571cbb0
Merge branch 'app-stock-coverage' of https://github.com/matmair/Inven…
matmair Sep 25, 2024
1c72e02
make report assertation dynamic
matmair Sep 25, 2024
4aa3bbe
add migration test
matmair Sep 25, 2024
b02d909
extend validation plugin tests
matmair Sep 25, 2024
2694060
disable flaky test
matmair Sep 25, 2024
1a43533
Merge branch 'master' of https://github.com/inventree/InvenTree into …
matmair Sep 25, 2024
93a5d92
Add test for barcode/uid transition
matmair Sep 25, 2024
33a20ec
test reverse migration
matmair Sep 25, 2024
527fc69
cleanup new test
matmair Sep 25, 2024
ade1806
remove empty action
matmair Sep 25, 2024
83ab2d4
split and refactor API tests
matmair Sep 26, 2024
30ae691
refactor test
matmair Sep 26, 2024
0421301
Add test for error conditions
matmair Sep 26, 2024
2a18462
Merge branch 'master' into app-stock-coverage
matmair Sep 26, 2024
b170d52
fix double entry
matmair Sep 26, 2024
32b1b08
more migration tests
matmair Sep 26, 2024
64abe6d
Merge branch 'app-stock-coverage' of https://github.com/matmair/Inven…
matmair Sep 26, 2024
2a468b0
also test no history
matmair Sep 26, 2024
e16d254
Merge branch 'master' into app-stock-coverage
matmair Sep 26, 2024
ae497ca
Merge branch 'app-stock-coverage' of https://github.com/matmair/Inven…
matmair Sep 26, 2024
8d90814
fix assertation
matmair Sep 27, 2024
abf6195
add another migration test
matmair Sep 27, 2024
f4a72ca
fix typo
matmair Sep 27, 2024
9eac47e
fix manufacturer filter
matmair Sep 27, 2024
62548af
test more filters
matmair Sep 27, 2024
d364d32
even more filter tests
matmair Sep 27, 2024
e4dae44
move top level test to right place
matmair Sep 27, 2024
fe3c71b
add todos for tests that could be more expressive
matmair Sep 27, 2024
e8e7bfd
add test for checking duplicate serials
matmair Sep 27, 2024
9c0d1b2
ignore cautious catches
matmair Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/backend/InvenTree/common/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@
import common.validators
from common.settings import get_global_setting, set_global_setting
from InvenTree.helpers import str2bool
from InvenTree.unit_test import InvenTreeAPITestCase, InvenTreeTestCase, PluginMixin
from InvenTree.unit_test import (
AdminTestCase,
InvenTreeAPITestCase,
InvenTreeTestCase,
PluginMixin,
)
from part.models import Part
from plugin import registry
from plugin.models import NotificationUserSetting
Expand Down Expand Up @@ -1676,3 +1681,14 @@ def test_validation(self):
self.assertEqual(
instance.__str__(), 'Stock Item (StockStatus): OK - advanced | 11 (10)'
)


class AdminTest(AdminTestCase):
"""Tests for the admin interface integration."""

def test_admin(self):
"""Test the admin URL."""
self.helper(
model=Attachment,
model_kwargs={'link': 'https://aa.example.org', 'model_id': 1},
)
1 change: 0 additions & 1 deletion src/backend/InvenTree/plugin/mixins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
'SingleNotificationMethod',
'SupplierBarcodeMixin',
'UrlsMixin',
'UrlsMixin',
'UserInterfaceMixin',
'ValidationMixin',
]
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
"""Unit tests for the SampleValidatorPlugin class."""

from django.core.exceptions import ValidationError
from django.urls import reverse

import build.models
import part.models
from InvenTree.unit_test import InvenTreeTestCase
from InvenTree.unit_test import InvenTreeAPITestCase, InvenTreeTestCase
from plugin.registry import registry


class SampleValidatorPluginTest(InvenTreeTestCase):
class SampleValidatorPluginTest(InvenTreeAPITestCase, InvenTreeTestCase):
"""Tests for the SampleValidatonPlugin class."""

fixtures = ['category', 'location']
fixtures = ['part', 'category', 'location', 'build']

def setUp(self):
"""Set up the test environment."""
Expand All @@ -28,6 +30,7 @@ def setUp(self):
self.bom_item = part.models.BomItem.objects.create(
part=self.assembly, sub_part=self.part, quantity=1
)
super().setUp()

def get_plugin(self):
"""Return the SampleValidatorPlugin instance."""
Expand Down Expand Up @@ -113,3 +116,40 @@ def test_validate_ipn(self):
self.part.IPN = 'LMNOPQ'

self.part.save()

def test_validate_generate_batch_code(self):
"""Test the generate_batch_code function."""
self.enable_plugin(True)
plg = self.get_plugin()
self.assertIsNotNone(plg)

code = plg.generate_batch_code()
self.assertIsInstance(code, str)
self.assertTrue(code.startswith('SAMPLE-BATCH'))

def test_api_batch(self):
"""Test the batch code validation API."""
self.enable_plugin(True)
url = reverse('api-generate-batch-code')

response = self.post(url)
self.assertIn('batch_code', response.data)
self.assertTrue(response.data['batch_code'].startswith('SAMPLE-BATCH'))

# Use part code
part_itm = part.models.Part.objects.first()
response = self.post(url, {'part': part_itm.pk})
self.assertIn('batch_code', response.data)
self.assertTrue(
response.data['batch_code'].startswith(part_itm.name + '-SAMPLE-BATCH')
)

# Use build_order
build_itm = build.models.Build.objects.first()
response = self.post(url, {'build_order': build_itm.pk})
self.assertIn('batch_code', response.data)
self.assertTrue(
response.data['batch_code'].startswith(
build_itm.reference + '-SAMPLE-BATCH'
)
)
27 changes: 27 additions & 0 deletions src/backend/InvenTree/report/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from common.models import Attachment, InvenTreeSetting
from InvenTree.unit_test import AdminTestCase, InvenTreeAPITestCase
from order.models import ReturnOrder, SalesOrder
from part.models import Part
from plugin.registry import registry
from report.models import LabelTemplate, ReportTemplate
from report.templatetags import barcode as barcode_tags
Expand Down Expand Up @@ -305,6 +306,16 @@ def test_list_endpoint(self):
response = self.get(url, {'enabled': False})
self.assertEqual(len(response.data), n)

# Filter by items
part_pk = Part.objects.first().pk
report = ReportTemplate.objects.filter(model_type='part').first()
return
# TODO @matmair re-enable this (in GitHub Actions) flaky test
response = self.get(url, {'model_type': 'part', 'items': part_pk})
self.assertEqual(len(response.data), 1)
self.assertEqual(response.data[0]['pk'], report.pk)
self.assertEqual(response.data[0]['name'], report.name)

def test_create_endpoint(self):
"""Test that creating a new report works for each report."""
url = reverse('api-report-template-list')
Expand Down Expand Up @@ -533,6 +544,22 @@ def run_print_test(self, qs, model_type, label: bool = True):
max_query_count=500 * len(qs),
)

# Test with wrong dimensions
if not hasattr(template, 'width'):
return

org_width = template.width
template.width = 0
template.save()
response = self.post(
url,
{'template': template.pk, 'plugin': plugin.pk, 'items': [qs[0].pk]},
expected_code=400,
)
self.assertEqual(str(response.data['template'][0]), 'Invalid label dimensions')
template.width = org_width
template.save()


class TestReportTest(PrintTestMixins, ReportTest):
"""Unit testing class for the stock item TestReport model."""
Expand Down
25 changes: 13 additions & 12 deletions src/backend/InvenTree/stock/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def get_serializer(self, *args, **kwargs):
params.get('supplier_part_detail', True)
)
kwargs['path_detail'] = str2bool(params.get('path_detail', False))
except AttributeError:
except AttributeError: # pragma: no cover
pass

return self.serializer_class(*args, **kwargs)
Expand All @@ -164,7 +164,7 @@ def get_serializer_context(self):

try:
context['item'] = StockItem.objects.get(pk=self.kwargs.get('pk', None))
except Exception:
except Exception: # pragma: no cover
pass

return context
Expand Down Expand Up @@ -526,7 +526,8 @@ class Meta:
def filter_manufacturer(self, queryset, name, company):
"""Filter by manufacturer."""
return queryset.filter(
Q(is_manufacturer=True) & Q(manufacturer_part__manufacturer=company)
Q(supplier_part__manufacturer_part__manufacturer__is_manufacturer=True)
& Q(supplier_part__manufacturer_part__manufacturer=company)
)

supplier = rest_filters.ModelChoiceFilter(
Expand Down Expand Up @@ -891,7 +892,7 @@ def get_serializer(self, *args, **kwargs):
'tests',
]:
kwargs[key] = str2bool(params.get(key, False))
except AttributeError:
except AttributeError: # pragma: no cover
pass

kwargs['context'] = self.get_serializer_context()
Expand Down Expand Up @@ -982,7 +983,7 @@ def create(self, request, *args, **kwargs):
data['purchase_price'] = float(
data['purchase_price']
) / float(supplier_part.pack_quantity_native)
except ValueError:
except ValueError: # pragma: no cover
pass

# Now remove the flag from data, so that it doesn't interfere with saving
Expand Down Expand Up @@ -1096,7 +1097,7 @@ def filter_queryset(self, queryset):
pk__in=[it.pk for it in item.get_descendants(include_self=True)]
)

except (ValueError, StockItem.DoesNotExist):
except (ValueError, StockItem.DoesNotExist): # pragma: no cover
pass

# Exclude StockItems which are already allocated to a particular SalesOrder
Expand All @@ -1114,7 +1115,7 @@ def filter_queryset(self, queryset):
# Exclude any stock item which is already allocated to the sales order
queryset = queryset.exclude(pk__in=[a.item.pk for a in allocations])

except (ValueError, SalesOrder.DoesNotExist):
except (ValueError, SalesOrder.DoesNotExist): # pragma: no cover
pass

# Does the client wish to filter by the Part ID?
Expand Down Expand Up @@ -1160,7 +1161,7 @@ def filter_queryset(self, queryset):
else:
queryset = queryset.filter(location=loc_id)

except (ValueError, StockLocation.DoesNotExist):
except (ValueError, StockLocation.DoesNotExist): # pragma: no cover
pass

return queryset
Expand Down Expand Up @@ -1223,7 +1224,7 @@ def get_serializer(self, *args, **kwargs):
kwargs['template_detail'] = str2bool(
self.request.query_params.get('template_detail', False)
)
except Exception:
except Exception: # pragma: no cover
pass

kwargs['context'] = self.get_serializer_context()
Expand Down Expand Up @@ -1363,7 +1364,7 @@ def filter_queryset(self, queryset):

queryset = queryset.filter(stock_item__in=items)

except (ValueError, StockItem.DoesNotExist):
except (ValueError, StockItem.DoesNotExist): # pragma: no cover
pass

return queryset
Expand Down Expand Up @@ -1405,14 +1406,14 @@ def get_serializer(self, *args, **kwargs):
kwargs['item_detail'] = str2bool(
self.request.query_params.get('item_detail', False)
)
except Exception:
except Exception: # pragma: no cover
pass

try:
kwargs['user_detail'] = str2bool(
self.request.query_params.get('user_detail', False)
)
except Exception:
except Exception: # pragma: no cover
pass

kwargs['context'] = self.get_serializer_context()
Expand Down
1 change: 1 addition & 0 deletions src/backend/InvenTree/stock/fixtures/location.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
tree_id: 2
lft: 1
rght: 8
external: True

- model: stock.stocklocation
pk: 5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,6 @@
from django.db import migrations
import djmoney.models.fields

from django.db.migrations.recorder import MigrationRecorder


def show_migrations(apps, schema_editor):
"""Show the latest migrations from each app"""

for app in apps.get_app_configs():

label = app.label

migrations = MigrationRecorder.Migration.objects.filter(app=app).order_by('-applied')[:5]

print(f"{label} migrations:")
for m in migrations:
print(f" - {m.name}")

matmair marked this conversation as resolved.
Show resolved Hide resolved

class Migration(migrations.Migration):

Expand All @@ -30,10 +14,6 @@ class Migration(migrations.Migration):
operations = []

xoperations = [
migrations.RunPython(
code=show_migrations,
reverse_code=migrations.RunPython.noop
),
migrations.AlterField(
model_name='stockitem',
name='purchase_price',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def update_templates(apps, schema_editor):

# For each bad result, attempt to find a matching template
# Here, a matching template must point to a part *above* the part in the tree
# Annotate the queryset with a "mathching template"
# Annotate the queryset with a "matching template"

template_query = PartTestTemplate.objects.filter(
part__tree_id=OuterRef('stock_item__part__tree_id'),
Expand Down
Loading
Loading