2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-07-01 03:00:54 +00:00

[CI] docstrings (#6172)

* Squashed commit of the following:

commit 52d7ff0f65
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 23:03:20 2024 +0100

    fixed lookup

commit 0d076eaea8
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 23:03:08 2024 +0100

    switched to pathlib for lookup

commit 473e75eda2
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 22:52:30 2024 +0100

    fix wrong url response

commit fd74f8d703
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 21:14:38 2024 +0100

    switched to ruff for import sorting

commit f83fedbbb8
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 21:03:14 2024 +0100

    switched to single quotes everywhere

commit a92442e60e
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:58:23 2024 +0100

    added autofixes

commit cc66c93136
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:56:47 2024 +0100

    enable autoformat

commit 1f343606ec
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:42:14 2024 +0100

    Squashed commit of the following:

    commit f5cf7b2e78
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 20:36:57 2024 +0100

        fixed reqs

    commit 9d845bee98
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 20:32:35 2024 +0100

        disable autofix/format

    commit aff5f27148
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 20:28:50 2024 +0100

        adjust checks

    commit 47271cf1ef
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 20:28:22 2024 +0100

        reorder order of operations

    commit e1bf178b40
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 20:01:09 2024 +0100

        adapted ruff settings to better fit code base

    commit ad7d88a6f4
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 19:59:45 2024 +0100

        auto fixed docstring

    commit a2e54a760e
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 19:46:35 2024 +0100

        fix getattr useage

    commit cb80c73bc6
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 19:25:09 2024 +0100

        fix requirements file

    commit b7780bbd21
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:42:28 2024 +0100

        fix removed sections

    commit 71f1681f55
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:41:21 2024 +0100

        fix djlint syntax

    commit a0bcf1bcce
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:35:28 2024 +0100

        remove flake8 from code base

    commit 22475b31cc
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:34:56 2024 +0100

        remove flake8 from code base

    commit 0413350f14
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:24:39 2024 +0100

        moved ruff section

    commit d90c48a0bf
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:24:24 2024 +0100

        move djlint config to pyproject

    commit c5ce55d511
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:20:39 2024 +0100

        added isort again

    commit 42a41d23af
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:19:02 2024 +0100

        move config section

    commit 8569233181
    Author: Matthias Mair <code@mjmair.com>
    Date:   Sun Jan 7 18:17:52 2024 +0100

        fix codespell error

    commit 2897c6704d
    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:

commit d3b795824b
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 22:56:17 2024 +0100

    fixed source path

commit 0bac0c19b8
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 22:47:53 2024 +0100

    fixed req

commit 9f61f01d9c
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 22:45:18 2024 +0100

    added missing toml req

commit 91b71ed24a
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:49:50 2024 +0100

    moved isort config

commit 12460b0419
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:43:22 2024 +0100

    remove flake8 section from setup.cfg

commit f5cf7b2e78
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:36:57 2024 +0100

    fixed reqs

commit 9d845bee98
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:32:35 2024 +0100

    disable autofix/format

commit aff5f27148
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:28:50 2024 +0100

    adjust checks

commit 47271cf1ef
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:28:22 2024 +0100

    reorder order of operations

commit e1bf178b40
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 20:01:09 2024 +0100

    adapted ruff settings to better fit code base

commit ad7d88a6f4
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 19:59:45 2024 +0100

    auto fixed docstring

commit a2e54a760e
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 19:46:35 2024 +0100

    fix getattr useage

commit cb80c73bc6
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 19:25:09 2024 +0100

    fix requirements file

commit b7780bbd21
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:42:28 2024 +0100

    fix removed sections

commit 71f1681f55
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:41:21 2024 +0100

    fix djlint syntax

commit a0bcf1bcce
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:35:28 2024 +0100

    remove flake8 from code base

commit 22475b31cc
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:34:56 2024 +0100

    remove flake8 from code base

commit 0413350f14
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:24:39 2024 +0100

    moved ruff section

commit d90c48a0bf
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:24:24 2024 +0100

    move djlint config to pyproject

commit c5ce55d511
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:20:39 2024 +0100

    added isort again

commit 42a41d23af
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:19:02 2024 +0100

    move config section

commit 8569233181
Author: Matthias Mair <code@mjmair.com>
Date:   Sun Jan 7 18:17:52 2024 +0100

    fix codespell error

commit 2897c6704d
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
This commit is contained in:
Matthias Mair
2024-01-11 04:40:07 +01:00
committed by GitHub
parent 9db3efa085
commit 9d0264c319
168 changed files with 1659 additions and 1754 deletions

View File

@ -256,7 +256,7 @@ class StockItemResource(InvenTreeResource):
)
def dehydrate_purchase_price(self, item):
"""Render purchase pric as float"""
"""Render purchase pric as float."""
if item.purchase_price is not None:
return float(item.purchase_price.amount)

View File

@ -161,13 +161,13 @@ class StockItemUninstall(StockItemContextMixin, CreateAPI):
class StockItemConvert(StockItemContextMixin, CreateAPI):
"""API endpoint for converting a stock item to a variant part"""
"""API endpoint for converting a stock item to a variant part."""
serializer_class = StockSerializers.ConvertStockItemSerializer
class StockItemReturn(StockItemContextMixin, CreateAPI):
"""API endpoint for returning a stock item from a customer"""
"""API endpoint for returning a stock item from a customer."""
serializer_class = StockSerializers.ReturnStockItemSerializer
@ -262,7 +262,7 @@ class StockLocationFilter(rest_filters.FilterSet):
)
def filter_has_location_type(self, queryset, name, value):
"""Filter by whether or not the location has a location type"""
"""Filter by whether or not the location has a location type."""
if str2bool(value):
return queryset.exclude(location_type=None)
return queryset.filter(location_type=None)
@ -280,7 +280,7 @@ class StockLocationList(APIDownloadMixin, ListCreateAPI):
filterset_class = StockLocationFilter
def download_queryset(self, queryset, export_format):
"""Download the filtered queryset as a data file"""
"""Download the filtered queryset as a data file."""
dataset = LocationResource().export(queryset=queryset)
filedata = dataset.export(export_format)
filename = f'InvenTree_Locations.{export_format}'
@ -288,7 +288,7 @@ class StockLocationList(APIDownloadMixin, ListCreateAPI):
return DownloadFile(filedata, filename)
def get_queryset(self, *args, **kwargs):
"""Return annotated queryset for the StockLocationList endpoint"""
"""Return annotated queryset for the StockLocationList endpoint."""
queryset = super().get_queryset(*args, **kwargs)
queryset = StockSerializers.LocationSerializer.annotate_queryset(queryset)
return queryset
@ -431,7 +431,7 @@ class StockFilter(rest_filters.FilterSet):
"""FilterSet for StockItem LIST API."""
class Meta:
"""Metaclass options for this filterset"""
"""Metaclass options for this filterset."""
model = StockItem
@ -505,7 +505,7 @@ class StockFilter(rest_filters.FilterSet):
status = rest_filters.NumberFilter(label='Status Code', method='filter_status')
def filter_status(self, queryset, name, value):
"""Filter by integer status code"""
"""Filter by integer status code."""
return queryset.filter(status=value)
allocated = rest_filters.BooleanFilter(
@ -513,7 +513,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_allocated(self, queryset, name, value):
"""Filter by whether or not the stock item is 'allocated'"""
"""Filter by whether or not the stock item is 'allocated'."""
if str2bool(value):
# Filter StockItem with either build allocations or sales order allocations
return queryset.filter(
@ -527,7 +527,7 @@ class StockFilter(rest_filters.FilterSet):
expired = rest_filters.BooleanFilter(label='Expired', method='filter_expired')
def filter_expired(self, queryset, name, value):
"""Filter by whether or not the stock item has expired"""
"""Filter by whether or not the stock item has expired."""
if not common.settings.stock_expiry_enabled():
return queryset
@ -540,7 +540,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_external(self, queryset, name, value):
"""Filter by whether or not the stock item is located in an external location"""
"""Filter by whether or not the stock item is located in an external location."""
if str2bool(value):
return queryset.filter(location__external=True)
return queryset.exclude(location__external=True)
@ -687,7 +687,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_ancestor(self, queryset, name, ancestor):
"""Filter based on ancestor stock item"""
"""Filter based on ancestor stock item."""
return queryset.filter(parent__in=ancestor.get_descendants(include_self=True))
category = rest_filters.ModelChoiceFilter(
@ -697,8 +697,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_category(self, queryset, name, category):
"""Filter based on part category"""
"""Filter based on part category."""
child_categories = category.get_descendants(include_self=True)
return queryset.filter(part__category__in=child_categories)
@ -708,8 +707,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_bom_item(self, queryset, name, bom_item):
"""Filter based on BOM item"""
"""Filter based on BOM item."""
return queryset.filter(bom_item.get_stock_filter())
part_tree = rest_filters.ModelChoiceFilter(
@ -717,7 +715,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_part_tree(self, queryset, name, part_tree):
"""Filter based on part tree"""
"""Filter based on part tree."""
return queryset.filter(part__tree_id=part_tree.tree_id)
company = rest_filters.ModelChoiceFilter(
@ -725,7 +723,7 @@ class StockFilter(rest_filters.FilterSet):
)
def filter_company(self, queryset, name, company):
"""Filter by company (either manufacturer or supplier)"""
"""Filter by company (either manufacturer or supplier)."""
return queryset.filter(
Q(supplier_part__supplier=company)
| Q(supplier_part__manufacturer_part__manufacturer=company)
@ -752,7 +750,6 @@ class StockFilter(rest_filters.FilterSet):
def filter_stale(self, queryset, name, value):
"""Filter by stale stock items."""
stale_days = common.models.InvenTreeSetting.get_setting('STOCK_STALE_DAYS')
if stale_days <= 0:
@ -1452,7 +1449,7 @@ class LocationDetail(CustomRetrieveUpdateDestroyAPI):
serializer_class = StockSerializers.LocationSerializer
def get_serializer(self, *args, **kwargs):
"""Add extra context to serializer based on provided query parameters"""
"""Add extra context to serializer based on provided query parameters."""
try:
params = self.request.query_params
@ -1465,14 +1462,13 @@ class LocationDetail(CustomRetrieveUpdateDestroyAPI):
return self.serializer_class(*args, **kwargs)
def get_queryset(self, *args, **kwargs):
"""Return annotated queryset for the StockLocationList endpoint"""
"""Return annotated queryset for the StockLocationList endpoint."""
queryset = super().get_queryset(*args, **kwargs)
queryset = StockSerializers.LocationSerializer.annotate_queryset(queryset)
return queryset
def destroy(self, request, *args, **kwargs):
"""Delete a Stock location instance via the API"""
"""Delete a Stock location instance via the API."""
delete_stock_items = str(request.data.get('delete_stock_items', 0)) == '1'
delete_sub_locations = str(request.data.get('delete_sub_locations', 0)) == '1'

View File

@ -1,4 +1,4 @@
"""Custom query filters for the Stock models"""
"""Custom query filters for the Stock models."""
from django.db.models import F, Func, IntegerField, OuterRef, Q, Subquery
from django.db.models.functions import Coalesce

View File

@ -119,7 +119,7 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
objects = StockLocationManager()
class Meta:
"""Metaclass defines extra model properties"""
"""Metaclass defines extra model properties."""
verbose_name = _('Stock Location')
verbose_name_plural = _('Stock Locations')
@ -131,7 +131,6 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
This must be handled within a transaction.atomic(), otherwise the tree structure is damaged
"""
super().delete(
delete_children=kwargs.get('delete_sub_locations', False),
delete_items=kwargs.get('delete_stock_items', False),
@ -201,8 +200,9 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
@icon.setter
def icon(self, value):
"""Setter to keep model API compatibility. But be careful:
"""Setter to keep model API compatibility.
But be careful:
If the field gets loaded as default value by any form which is later saved,
the location no longer inherits its icon from the location type.
"""
@ -243,9 +243,9 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
return owner.is_user_allowed(user, include_group=True)
def clean(self):
"""Custom clean action for the StockLocation model:
"""Custom clean action for the StockLocation model.
- Ensure stock location can't be made structural if stock items already located to them
Ensure stock location can't be made structural if stock items already located to them
"""
if self.pk and self.structural and self.stock_item_count(False) > 0:
raise ValidationError(
@ -288,7 +288,7 @@ class StockLocation(InvenTreeBarcodeMixin, MetadataMixin, InvenTreeTree):
return self.stock_item_count()
def get_items(self, cascade=False):
"""Return a queryset for all stock items under this category"""
"""Return a queryset for all stock items under this category."""
return self.get_stock_items(cascade=cascade)
@ -904,7 +904,7 @@ class StockItem(
@property
def status_text(self):
"""Return the text representation of the status field"""
"""Return the text representation of the status field."""
return StockStatus.text(self.status)
purchase_price = InvenTreeModelMoneyField(
@ -1669,6 +1669,7 @@ class StockItem(
Args:
quantity: Number of stock items to remove from this entity, and pass to the next
location: Where to move the new StockItem to
user: User performing the action
kwargs:
notes: Optional notes for tracking
@ -1752,7 +1753,7 @@ class StockItem(
@classmethod
def optional_transfer_fields(cls):
"""Returns a list of optional fields for a stock transfer"""
"""Returns a list of optional fields for a stock transfer."""
return ['batch', 'status', 'packaging']
@transaction.atomic

View File

@ -218,7 +218,7 @@ class StockItemSerializer(InvenTree.serializers.InvenTreeTagModelSerializer):
)
def validate_part(self, part):
"""Ensure the provided Part instance is valid"""
"""Ensure the provided Part instance is valid."""
if part.virtual:
raise ValidationError(_('Stock item cannot be created for virtual parts'))
@ -506,7 +506,6 @@ class InstallStockItemSerializer(serializers.Serializer):
def validate_quantity(self, quantity):
"""Validate the quantity value."""
if quantity < 1:
raise ValidationError(_('Quantity to install must be at least 1'))
@ -528,8 +527,7 @@ class InstallStockItemSerializer(serializers.Serializer):
return stock_item
def validate(self, data):
"""Ensure that the provided dataset is valid"""
"""Ensure that the provided dataset is valid."""
stock_item = data['stock_item']
quantity = data.get('quantity', stock_item.quantity)
@ -596,10 +594,10 @@ class UninstallStockItemSerializer(serializers.Serializer):
class ConvertStockItemSerializer(serializers.Serializer):
"""DRF serializer class for converting a StockItem to a valid variant part"""
"""DRF serializer class for converting a StockItem to a valid variant part."""
class Meta:
"""Metaclass options"""
"""Metaclass options."""
fields = ['part']
@ -613,7 +611,7 @@ class ConvertStockItemSerializer(serializers.Serializer):
)
def validate_part(self, part):
"""Ensure that the provided part is a valid option for the stock item"""
"""Ensure that the provided part is a valid option for the stock item."""
stock_item = self.context['item']
valid_options = stock_item.part.get_conversion_options()
@ -625,8 +623,9 @@ class ConvertStockItemSerializer(serializers.Serializer):
return part
def validate(self, data):
"""Ensure that the stock item is valid for conversion:
"""Ensure that the stock item is valid for conversion.
Rules:
- If a SupplierPart is assigned, we cannot convert!
"""
data = super().validate(data)
@ -641,7 +640,7 @@ class ConvertStockItemSerializer(serializers.Serializer):
return data
def save(self):
"""Save the serializer to convert the StockItem to the selected Part"""
"""Save the serializer to convert the StockItem to the selected Part."""
data = self.validated_data
part = data['part']
@ -653,10 +652,10 @@ class ConvertStockItemSerializer(serializers.Serializer):
class ReturnStockItemSerializer(serializers.Serializer):
"""DRF serializer for returning a stock item from a customer"""
"""DRF serializer for returning a stock item from a customer."""
class Meta:
"""Metaclass options"""
"""Metaclass options."""
fields = ['location', 'note']
@ -677,7 +676,7 @@ class ReturnStockItemSerializer(serializers.Serializer):
)
def save(self):
"""Save the serialzier to return the item into stock"""
"""Save the serialzier to return the item into stock."""
item = self.context['item']
request = self.context['request']
@ -690,10 +689,10 @@ class ReturnStockItemSerializer(serializers.Serializer):
class StockChangeStatusSerializer(serializers.Serializer):
"""Serializer for changing status of multiple StockItem objects"""
"""Serializer for changing status of multiple StockItem objects."""
class Meta:
"""Metaclass options"""
"""Metaclass options."""
fields = ['items', 'status', 'note']
@ -707,7 +706,7 @@ class StockChangeStatusSerializer(serializers.Serializer):
)
def validate_items(self, items):
"""Validate the selected stock items"""
"""Validate the selected stock items."""
if len(items) == 0:
raise ValidationError(_('No stock items selected'))
@ -728,7 +727,7 @@ class StockChangeStatusSerializer(serializers.Serializer):
@transaction.atomic
def save(self):
"""Save the serializer to change the status of the selected stock items"""
"""Save the serializer to change the status of the selected stock items."""
data = self.validated_data
items = data['items']
@ -837,7 +836,7 @@ class LocationSerializer(InvenTree.serializers.InvenTreeTagModelSerializer):
read_only_fields = ['barcode_hash', 'icon']
def __init__(self, *args, **kwargs):
"""Optionally add or remove extra fields"""
"""Optionally add or remove extra fields."""
path_detail = kwargs.pop('path_detail', False)
super().__init__(*args, **kwargs)
@ -847,7 +846,7 @@ class LocationSerializer(InvenTree.serializers.InvenTreeTagModelSerializer):
@staticmethod
def annotate_queryset(queryset):
"""Annotate extra information to the queryset"""
"""Annotate extra information to the queryset."""
# Annotate the number of stock items which exist in this category (including subcategories)
queryset = queryset.annotate(items=stock.filters.annotate_location_items())

View File

@ -66,7 +66,7 @@ class StockLocationTest(StockAPITestCase):
StockLocation.objects.create(name='top', description='top category')
def test_list(self):
"""Test the StockLocationList API endpoint"""
"""Test the StockLocationList API endpoint."""
test_cases = [
({}, 8, 'no parameters'),
({'parent': 1, 'cascade': False}, 2, 'Filter by parent, no cascading'),
@ -165,7 +165,7 @@ class StockLocationTest(StockAPITestCase):
self.post(self.list_url, data, expected_code=201)
def test_stock_location_delete(self):
"""Test stock location deletion with different parameters"""
"""Test stock location deletion with different parameters."""
class Target(IntEnum):
move_sub_locations_to_parent_move_stockitems_to_parent = (0,)
@ -294,7 +294,7 @@ class StockLocationTest(StockAPITestCase):
self.assertEqual(child.parent, parent_stock_location)
def test_stock_location_structural(self):
"""Test the effectiveness of structural stock locations
"""Test the effectiveness of structural stock locations.
Make sure:
- Stock items cannot be created in structural locations
@ -530,7 +530,7 @@ class StockItemListTest(StockAPITestCase):
return response.data
def test_top_level_filtering(self):
"""Test filtering against "top level" stock location"""
"""Test filtering against "top level" stock location."""
# No filters, should return *all* items
response = self.get(self.list_url, {}, expected_code=200)
self.assertEqual(len(response.data), StockItem.objects.count())
@ -628,7 +628,7 @@ class StockItemListTest(StockAPITestCase):
self.assertEqual(len(response), 1)
def test_filter_by_company(self):
"""Test that we can filter stock items by company"""
"""Test that we can filter stock items by company."""
for cmp in company.models.Company.objects.all():
self.get_stock(company=cmp.pk)
@ -787,14 +787,14 @@ class StockItemListTest(StockAPITestCase):
self.assertEqual(len(dataset), 17)
def test_filter_by_allocated(self):
"""Test that we can filter by "allocated" status:
"""Test that we can filter by "allocated" status.
Rules:
- Only return stock items which are 'allocated'
- Either to a build order or sales order
- Test that the results are "distinct" (no duplicated results)
- Ref: https://github.com/inventree/InvenTree/pull/5916
"""
# Create a build order to allocate to
assembly = part.models.Part.objects.create(
name='F Assembly', description='Assembly for filter test', assembly=True
@ -1284,7 +1284,7 @@ class StockItemTest(StockAPITestCase):
self.assertEqual(sub_item.location.pk, 1)
def test_return_from_customer(self):
"""Test that we can return a StockItem from a customer, via the API"""
"""Test that we can return a StockItem from a customer, via the API."""
# Assign item to customer
item = StockItem.objects.get(pk=521)
customer = company.models.Company.objects.get(pk=4)
@ -1316,7 +1316,7 @@ class StockItemTest(StockAPITestCase):
self.assertIsNone(item.customer)
def test_convert_to_variant(self):
"""Test that we can convert a StockItem to a variant part via the API"""
"""Test that we can convert a StockItem to a variant part via the API."""
category = part.models.PartCategory.objects.get(pk=3)
# First, construct a set of template / variant parts
@ -1361,7 +1361,7 @@ class StockItemTest(StockAPITestCase):
self.assertEqual(stock_item.part, variant)
def test_set_status(self):
"""Test API endpoint for setting StockItem status"""
"""Test API endpoint for setting StockItem status."""
url = reverse('api-stock-change-status')
prt = Part.objects.first()
@ -1612,7 +1612,7 @@ class StockTestResultTest(StockAPITestCase):
self.assertIsNotNone(response.data['attachment'])
def test_bulk_delete(self):
"""Test that the BulkDelete endpoint works for this model"""
"""Test that the BulkDelete endpoint works for this model."""
n = StockItemTestResult.objects.count()
tests = []
@ -1849,7 +1849,7 @@ class StockMetadataAPITest(InvenTreeAPITestCase):
roles = ['stock.change', 'stock_location.change']
def metatester(self, apikey, model):
"""Generic tester"""
"""Generic tester."""
modeldata = model.objects.first()
# Useless test unless a model object is found
@ -1875,7 +1875,7 @@ class StockMetadataAPITest(InvenTreeAPITestCase):
)
def test_metadata(self):
"""Test all endpoints"""
"""Test all endpoints."""
for apikey, model in {
'api-location-metadata': StockLocation,
'api-stock-test-result-metadata': StockItemTestResult,

View File

@ -1,4 +1,4 @@
"""Unit tests for data migrations in the 'stock' app"""
"""Unit tests for data migrations in the 'stock' app."""
from django_test_migrations.contrib.unittest_case import MigratorTestCase
@ -6,13 +6,13 @@ from InvenTree import unit_test
class TestSerialNumberMigration(MigratorTestCase):
"""Test data migration which updates serial numbers"""
"""Test data migration which updates serial numbers."""
migrate_from = ('stock', '0067_alter_stockitem_part')
migrate_to = ('stock', unit_test.getNewestMigrationFile('stock'))
def prepare(self):
"""Create initial data for this migration"""
"""Create initial data for this migration."""
Part = self.old_state.apps.get_model('part', 'part')
StockItem = self.old_state.apps.get_model('stock', 'stockitem')
@ -48,7 +48,7 @@ class TestSerialNumberMigration(MigratorTestCase):
self.big_ref_pk = item.pk
def test_migrations(self):
"""Test that the migrations have been applied correctly"""
"""Test that the migrations have been applied correctly."""
StockItem = self.new_state.apps.get_model('stock', 'stockitem')
# Check that the serial number integer conversion has been applied correctly
@ -68,13 +68,13 @@ class TestSerialNumberMigration(MigratorTestCase):
class TestScheduledForDeletionMigration(MigratorTestCase):
"""Test data migration for removing 'scheduled_for_deletion' field"""
"""Test data migration for removing 'scheduled_for_deletion' field."""
migrate_from = ('stock', '0066_stockitem_scheduled_for_deletion')
migrate_to = ('stock', unit_test.getNewestMigrationFile('stock'))
def prepare(self):
"""Create some initial stock items"""
"""Create some initial stock items."""
Part = self.old_state.apps.get_model('part', 'part')
StockItem = self.old_state.apps.get_model('stock', 'stockitem')
@ -128,7 +128,7 @@ class TestScheduledForDeletionMigration(MigratorTestCase):
self.assertEqual(StockItem.objects.count(), 29)
def test_migration(self):
"""Test that all stock items were actually removed"""
"""Test that all stock items were actually removed."""
StockItem = self.new_state.apps.get_model('stock', 'stockitem')
# All the "scheduled for deletion" items have been removed

View File

@ -28,10 +28,10 @@ class StockListTest(StockViewTestCase):
class StockDetailTest(StockViewTestCase):
"""Unit test for the 'stock detail' page"""
"""Unit test for the 'stock detail' page."""
def test_basic_info(self):
"""Test that basic stock item info is rendered"""
"""Test that basic stock item info is rendered."""
url = reverse('stock-item-detail', kwargs={'pk': 1})
response = self.client.get(url)

View File

@ -18,7 +18,7 @@ from .models import StockItem, StockItemTestResult, StockItemTracking, StockLoca
class StockTestBase(InvenTreeTestCase):
"""Base class for running Stock tests"""
"""Base class for running Stock tests."""
fixtures = [
'category',
@ -53,7 +53,7 @@ class StockTest(StockTestBase):
"""Tests to ensure that the stock location tree functions correctly."""
def test_pathstring(self):
"""Check that pathstring updates occur as expected"""
"""Check that pathstring updates occur as expected."""
a = StockLocation.objects.create(name='A')
b = StockLocation.objects.create(name='B', parent=a)
c = StockLocation.objects.create(name='C', parent=b)
@ -128,7 +128,7 @@ class StockTest(StockTestBase):
self.assertTrue(d.pathstring.endswith('DDDDDDDD'))
def test_link(self):
"""Test the link URL field validation"""
"""Test the link URL field validation."""
item = StockItem.objects.get(pk=1)
# Check that invalid URLs fail
@ -163,14 +163,14 @@ class StockTest(StockTestBase):
@override_settings(EXTRA_URL_SCHEMES=['ssh'])
def test_exteneded_schema(self):
"""Test that extended URL schemes are allowed"""
"""Test that extended URL schemes are allowed."""
item = StockItem.objects.get(pk=1)
item.link = 'ssh://user:pwd@deb.org:223'
item.save()
item.full_clean()
def test_serial_numbers(self):
"""Test serial number uniqueness"""
"""Test serial number uniqueness."""
# Ensure that 'global uniqueness' setting is enabled
InvenTreeSetting.set_setting('SERIAL_NUMBER_GLOBALLY_UNIQUE', True, self.user)
@ -456,7 +456,7 @@ class StockTest(StockTestBase):
self.assertFalse(it.add_stock(-10, None))
def test_allocate_to_customer(self):
"""Test allocating stock to a customer"""
"""Test allocating stock to a customer."""
it = StockItem.objects.get(pk=2)
n = it.quantity
an = n - 10
@ -486,7 +486,7 @@ class StockTest(StockTestBase):
self.assertIn('Allocated some stock', track.notes)
def test_return_from_customer(self):
"""Test removing previous allocated stock from customer"""
"""Test removing previous allocated stock from customer."""
it = StockItem.objects.get(pk=2)
# First establish total stock for this part
@ -887,10 +887,10 @@ class StockTest(StockTestBase):
class StockBarcodeTest(StockTestBase):
"""Run barcode tests for the stock app"""
"""Run barcode tests for the stock app."""
def test_stock_item_barcode_basics(self):
"""Simple tests for the StockItem barcode integration"""
"""Simple tests for the StockItem barcode integration."""
item = StockItem.objects.get(pk=1)
self.assertEqual(StockItem.barcode_model_type(), 'stockitem')
@ -906,7 +906,7 @@ class StockBarcodeTest(StockTestBase):
self.assertEqual(barcode, '{"stockitem": 1}')
def test_location_barcode_basics(self):
"""Simple tests for the StockLocation barcode integration"""
"""Simple tests for the StockLocation barcode integration."""
self.assertEqual(StockLocation.barcode_model_type(), 'stocklocation')
loc = StockLocation.objects.get(pk=1)