mirror of
https://github.com/inventree/InvenTree.git
synced 2025-07-02 19:50:59 +00:00
Docstring checks in QC checks (#3089)
* Add pre-commit to the stack * exclude static * Add locales to excludes * fix style errors * rename pipeline steps * also wait on precommit * make template matching simpler * Use the same code for python setup everywhere * use step and cache for python setup * move regular settings up into general envs * just use full update * Use invoke instead of static references * make setup actions more similar * use python3 * refactor names to be similar * fix runner version * fix references * remove incidential change * use matrix for os * Github can't do this right now * ignore docstyle errors * Add seperate docstring test * update flake call * do not fail on docstring * refactor setup into workflow * update reference * switch to action * resturcture * add bash statements * remove os from cache * update input checks * make code cleaner * fix boolean * no relative paths * install wheel by python * switch to install * revert back to simple wheel * refactor import export tests * move setup keys back to not disturbe tests * remove docstyle till that is fixed * update references * continue on error * add docstring test * use relativ action references * Change step / job docstrings * update to merge * reformat comments 1 * fix docstrings 2 * fix docstrings 3 * fix docstrings 4 * fix docstrings 5 * fix docstrings 6 * fix docstrings 7 * fix docstrings 8 * fix docstirns 9 * fix docstrings 10 * docstring adjustments * update the remaining docstrings * small docstring changes * fix function name * update support files for docstrings * Add missing args to docstrings * Remove outdated function * Add docstrings for the 'build' app * Make API code cleaner * add more docstrings for plugin app * Remove dead code for plugin settings No idea what that was even intended for * ignore __init__ files for docstrings * More docstrings * Update docstrings for the 'part' directory * Fixes for related_part functionality * Fix removed stuff from merge99676ee
* make more consistent * Show statistics for docstrings * add more docstrings * move specific register statements to make them clearer to understant * More docstrings for common * and more docstrings * and more * simpler call * docstrings for notifications * docstrings for common/tests * Add docs for common/models * Revert "move specific register statements to make them clearer to understant" This reverts commitca96654622
. * use typing here * Revert "Make API code cleaner" This reverts commit24fb68bd3e
. * docstring updates for the 'users' app * Add generic Meta info to simple Meta classes * remove unneeded unique_together statements * More simple metas * Remove unnecessary format specifier * Remove extra json format specifiers * Add docstrings for the 'plugin' app * Docstrings for the 'label' app * Add missing docstrings for the 'report' app * Fix build test regression * Fix top-level files * docstrings for InvenTree/InvenTree * reduce unneeded code * add docstrings * and more docstrings * more docstrings * more docstrings for stock * more docstrings * docstrings for order/views * Docstrings for various files in the 'order' app * Docstrings for order/test_api.py * Docstrings for order/serializers.py * Docstrings for order/admin.py * More docstrings for the order app * Add docstrings for the 'company' app * Add unit tests for rebuilding the reference fields * Prune out some more dead code * remove more dead code Co-authored-by: Oliver Walters <oliver.henry.walters@gmail.com>
This commit is contained in:
@ -1,6 +1,4 @@
|
||||
"""
|
||||
Unit testing for the Stock API
|
||||
"""
|
||||
"""Unit testing for the Stock API."""
|
||||
|
||||
import io
|
||||
import os
|
||||
@ -21,6 +19,7 @@ from stock.models import StockItem, StockLocation
|
||||
|
||||
|
||||
class StockAPITestCase(InvenTreeAPITestCase):
|
||||
"""Mixin for stock api tests."""
|
||||
|
||||
fixtures = [
|
||||
'category',
|
||||
@ -41,30 +40,28 @@ class StockAPITestCase(InvenTreeAPITestCase):
|
||||
'stock.delete',
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
|
||||
super().setUp()
|
||||
|
||||
|
||||
class StockLocationTest(StockAPITestCase):
|
||||
"""
|
||||
Series of API tests for the StockLocation API
|
||||
"""
|
||||
"""Series of API tests for the StockLocation API."""
|
||||
|
||||
list_url = reverse('api-location-list')
|
||||
|
||||
def setUp(self):
|
||||
"""Setup for all tests."""
|
||||
super().setUp()
|
||||
|
||||
# Add some stock locations
|
||||
StockLocation.objects.create(name='top', description='top category')
|
||||
|
||||
def test_list(self):
|
||||
"""Test StockLocation list."""
|
||||
# Check that we can request the StockLocation list
|
||||
response = self.client.get(self.list_url, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertGreaterEqual(len(response.data), 1)
|
||||
|
||||
def test_add(self):
|
||||
"""Test adding StockLocation."""
|
||||
# Check that we can add a new StockLocation
|
||||
data = {
|
||||
'parent': 1,
|
||||
@ -76,17 +73,12 @@ class StockLocationTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StockItemListTest(StockAPITestCase):
|
||||
"""
|
||||
Tests for the StockItem API LIST endpoint
|
||||
"""
|
||||
"""Tests for the StockItem API LIST endpoint."""
|
||||
|
||||
list_url = reverse('api-stock-list')
|
||||
|
||||
def get_stock(self, **kwargs):
|
||||
"""
|
||||
Filter stock and return JSON object
|
||||
"""
|
||||
|
||||
"""Filter stock and return JSON object."""
|
||||
response = self.client.get(self.list_url, format='json', data=kwargs)
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
@ -95,19 +87,13 @@ class StockItemListTest(StockAPITestCase):
|
||||
return response.data
|
||||
|
||||
def test_get_stock_list(self):
|
||||
"""
|
||||
List *all* StockItem objects.
|
||||
"""
|
||||
|
||||
"""List *all* StockItem objects."""
|
||||
response = self.get_stock()
|
||||
|
||||
self.assertEqual(len(response), 29)
|
||||
|
||||
def test_filter_by_part(self):
|
||||
"""
|
||||
Filter StockItem by Part reference
|
||||
"""
|
||||
|
||||
"""Filter StockItem by Part reference."""
|
||||
response = self.get_stock(part=25)
|
||||
|
||||
self.assertEqual(len(response), 17)
|
||||
@ -116,19 +102,13 @@ class StockItemListTest(StockAPITestCase):
|
||||
|
||||
self.assertEqual(len(response), 12)
|
||||
|
||||
def test_filter_by_IPN(self):
|
||||
"""
|
||||
Filter StockItem by IPN reference
|
||||
"""
|
||||
|
||||
def test_filter_by_ipn(self):
|
||||
"""Filter StockItem by IPN reference."""
|
||||
response = self.get_stock(IPN="R.CH")
|
||||
self.assertEqual(len(response), 3)
|
||||
|
||||
def test_filter_by_location(self):
|
||||
"""
|
||||
Filter StockItem by StockLocation reference
|
||||
"""
|
||||
|
||||
"""Filter StockItem by StockLocation reference."""
|
||||
response = self.get_stock(location=5)
|
||||
self.assertEqual(len(response), 1)
|
||||
|
||||
@ -142,10 +122,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertEqual(len(response), 18)
|
||||
|
||||
def test_filter_by_depleted(self):
|
||||
"""
|
||||
Filter StockItem by depleted status
|
||||
"""
|
||||
|
||||
"""Filter StockItem by depleted status."""
|
||||
response = self.get_stock(depleted=1)
|
||||
self.assertEqual(len(response), 1)
|
||||
|
||||
@ -153,10 +130,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertEqual(len(response), 28)
|
||||
|
||||
def test_filter_by_in_stock(self):
|
||||
"""
|
||||
Filter StockItem by 'in stock' status
|
||||
"""
|
||||
|
||||
"""Filter StockItem by 'in stock' status."""
|
||||
response = self.get_stock(in_stock=1)
|
||||
self.assertEqual(len(response), 26)
|
||||
|
||||
@ -164,10 +138,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertEqual(len(response), 3)
|
||||
|
||||
def test_filter_by_status(self):
|
||||
"""
|
||||
Filter StockItem by 'status' field
|
||||
"""
|
||||
|
||||
"""Filter StockItem by 'status' field."""
|
||||
codes = {
|
||||
StockStatus.OK: 27,
|
||||
StockStatus.DESTROYED: 1,
|
||||
@ -183,18 +154,12 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertEqual(len(response), num)
|
||||
|
||||
def test_filter_by_batch(self):
|
||||
"""
|
||||
Filter StockItem by batch code
|
||||
"""
|
||||
|
||||
"""Filter StockItem by batch code."""
|
||||
response = self.get_stock(batch='B123')
|
||||
self.assertEqual(len(response), 1)
|
||||
|
||||
def test_filter_by_serialized(self):
|
||||
"""
|
||||
Filter StockItem by serialized status
|
||||
"""
|
||||
|
||||
"""Filter StockItem by serialized status."""
|
||||
response = self.get_stock(serialized=1)
|
||||
self.assertEqual(len(response), 12)
|
||||
|
||||
@ -208,10 +173,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertIsNone(item['serial'])
|
||||
|
||||
def test_filter_by_has_batch(self):
|
||||
"""
|
||||
Test the 'has_batch' filter, which tests if the stock item has been assigned a batch code
|
||||
"""
|
||||
|
||||
"""Test the 'has_batch' filter, which tests if the stock item has been assigned a batch code."""
|
||||
with_batch = self.get_stock(has_batch=1)
|
||||
without_batch = self.get_stock(has_batch=0)
|
||||
|
||||
@ -227,11 +189,10 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertTrue(item['batch'] in [None, ''])
|
||||
|
||||
def test_filter_by_tracked(self):
|
||||
"""
|
||||
Test the 'tracked' filter.
|
||||
"""Test the 'tracked' filter.
|
||||
|
||||
This checks if the stock item has either a batch code *or* a serial number
|
||||
"""
|
||||
|
||||
tracked = self.get_stock(tracked=True)
|
||||
untracked = self.get_stock(tracked=False)
|
||||
|
||||
@ -248,10 +209,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertTrue(item['batch'] in blank and item['serial'] in blank)
|
||||
|
||||
def test_filter_by_expired(self):
|
||||
"""
|
||||
Filter StockItem by expiry status
|
||||
"""
|
||||
|
||||
"""Filter StockItem by expiry status."""
|
||||
# First, we can assume that the 'stock expiry' feature is disabled
|
||||
response = self.get_stock(expired=1)
|
||||
self.assertEqual(len(response), 29)
|
||||
@ -289,10 +247,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertEqual(len(response), 25)
|
||||
|
||||
def test_paginate(self):
|
||||
"""
|
||||
Test that we can paginate results correctly
|
||||
"""
|
||||
|
||||
"""Test that we can paginate results correctly."""
|
||||
for n in [1, 5, 10]:
|
||||
response = self.get_stock(limit=n)
|
||||
|
||||
@ -302,7 +257,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
self.assertEqual(len(response['results']), n)
|
||||
|
||||
def export_data(self, filters=None):
|
||||
|
||||
"""Helper to test exports."""
|
||||
if not filters:
|
||||
filters = {}
|
||||
|
||||
@ -321,10 +276,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
return dataset
|
||||
|
||||
def test_export(self):
|
||||
"""
|
||||
Test exporting of Stock data via the API
|
||||
"""
|
||||
|
||||
"""Test exporting of Stock data via the API."""
|
||||
dataset = self.export_data({})
|
||||
|
||||
# Check that *all* stock item objects have been exported
|
||||
@ -361,13 +313,12 @@ class StockItemListTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StockItemTest(StockAPITestCase):
|
||||
"""
|
||||
Series of API tests for the StockItem API
|
||||
"""
|
||||
"""Series of API tests for the StockItem API."""
|
||||
|
||||
list_url = reverse('api-stock-list')
|
||||
|
||||
def setUp(self):
|
||||
"""Setup for all tests."""
|
||||
super().setUp()
|
||||
# Create some stock locations
|
||||
top = StockLocation.objects.create(name='A', description='top')
|
||||
@ -376,11 +327,7 @@ class StockItemTest(StockAPITestCase):
|
||||
StockLocation.objects.create(name='C', description='location c', parent=top)
|
||||
|
||||
def test_create_default_location(self):
|
||||
"""
|
||||
Test the default location functionality,
|
||||
if a 'location' is not specified in the creation request.
|
||||
"""
|
||||
|
||||
"""Test the default location functionality, if a 'location' is not specified in the creation request."""
|
||||
# The part 'R_4K7_0603' (pk=4) has a default location specified
|
||||
|
||||
response = self.client.post(
|
||||
@ -423,10 +370,7 @@ class StockItemTest(StockAPITestCase):
|
||||
self.assertEqual(response.data['location'], None)
|
||||
|
||||
def test_stock_item_create(self):
|
||||
"""
|
||||
Test creation of a StockItem via the API
|
||||
"""
|
||||
|
||||
"""Test creation of a StockItem via the API."""
|
||||
# POST with an empty part reference
|
||||
|
||||
response = self.client.post(
|
||||
@ -476,10 +420,7 @@ class StockItemTest(StockAPITestCase):
|
||||
)
|
||||
|
||||
def test_creation_with_serials(self):
|
||||
"""
|
||||
Test that serialized stock items can be created via the API,
|
||||
"""
|
||||
|
||||
"""Test that serialized stock items can be created via the API."""
|
||||
trackable_part = part.models.Part.objects.create(
|
||||
name='My part',
|
||||
description='A trackable part',
|
||||
@ -537,8 +478,7 @@ class StockItemTest(StockAPITestCase):
|
||||
self.assertEqual(trackable_part.get_stock_count(), 10)
|
||||
|
||||
def test_default_expiry(self):
|
||||
"""
|
||||
Test that the "default_expiry" functionality works via the API.
|
||||
"""Test that the "default_expiry" functionality works via the API.
|
||||
|
||||
- If an expiry_date is specified, use that
|
||||
- Otherwise, check if the referenced part has a default_expiry defined
|
||||
@ -547,9 +487,7 @@ class StockItemTest(StockAPITestCase):
|
||||
|
||||
Notes:
|
||||
- Part <25> has a default_expiry of 10 days
|
||||
|
||||
"""
|
||||
|
||||
# First test - create a new StockItem without an expiry date
|
||||
data = {
|
||||
'part': 4,
|
||||
@ -587,10 +525,7 @@ class StockItemTest(StockAPITestCase):
|
||||
self.assertEqual(response.data['expiry_date'], expiry.isoformat())
|
||||
|
||||
def test_purchase_price(self):
|
||||
"""
|
||||
Test that we can correctly read and adjust purchase price information via the API
|
||||
"""
|
||||
|
||||
"""Test that we can correctly read and adjust purchase price information via the API."""
|
||||
url = reverse('api-stock-detail', kwargs={'pk': 1})
|
||||
|
||||
data = self.get(url, expected_code=200).data
|
||||
@ -648,8 +583,7 @@ class StockItemTest(StockAPITestCase):
|
||||
self.assertEqual(data['purchase_price_currency'], 'NZD')
|
||||
|
||||
def test_install(self):
|
||||
""" Test that stock item can be installed into antoher item, via the API """
|
||||
|
||||
"""Test that stock item can be installed into antoher item, via the API."""
|
||||
# Select the "parent" stock item
|
||||
parent_part = part.models.Part.objects.get(pk=100)
|
||||
|
||||
@ -731,16 +665,10 @@ class StockItemTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StocktakeTest(StockAPITestCase):
|
||||
"""
|
||||
Series of tests for the Stocktake API
|
||||
"""
|
||||
"""Series of tests for the Stocktake API."""
|
||||
|
||||
def test_action(self):
|
||||
"""
|
||||
Test each stocktake action endpoint,
|
||||
for validation
|
||||
"""
|
||||
|
||||
"""Test each stocktake action endpoint, for validation."""
|
||||
for endpoint in ['api-stock-count', 'api-stock-add', 'api-stock-remove']:
|
||||
|
||||
url = reverse(endpoint)
|
||||
@ -796,10 +724,7 @@ class StocktakeTest(StockAPITestCase):
|
||||
self.assertContains(response, 'Ensure this value is greater than or equal to 0', status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def test_transfer(self):
|
||||
"""
|
||||
Test stock transfers
|
||||
"""
|
||||
|
||||
"""Test stock transfers."""
|
||||
data = {
|
||||
'items': [
|
||||
{
|
||||
@ -825,12 +750,10 @@ class StocktakeTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StockItemDeletionTest(StockAPITestCase):
|
||||
"""
|
||||
Tests for stock item deletion via the API
|
||||
"""
|
||||
"""Tests for stock item deletion via the API."""
|
||||
|
||||
def test_delete(self):
|
||||
|
||||
"""Test stock item deletion."""
|
||||
n = StockItem.objects.count()
|
||||
|
||||
# Create and then delete a bunch of stock items
|
||||
@ -861,12 +784,14 @@ class StockItemDeletionTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StockTestResultTest(StockAPITestCase):
|
||||
"""Tests for StockTestResult APIs."""
|
||||
|
||||
def get_url(self):
|
||||
"""Helper funtion to get test-result api url."""
|
||||
return reverse('api-stock-test-result-list')
|
||||
|
||||
def test_list(self):
|
||||
|
||||
"""Test list endpoint."""
|
||||
url = self.get_url()
|
||||
response = self.client.get(url)
|
||||
|
||||
@ -878,6 +803,7 @@ class StockTestResultTest(StockAPITestCase):
|
||||
self.assertGreaterEqual(len(response.data), 4)
|
||||
|
||||
def test_post_fail(self):
|
||||
"""Test failing posts."""
|
||||
# Attempt to post a new test result without specifying required data
|
||||
|
||||
url = self.get_url()
|
||||
@ -907,8 +833,7 @@ class StockTestResultTest(StockAPITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
|
||||
def test_post(self):
|
||||
# Test creation of a new test result
|
||||
|
||||
"""Test creation of a new test result."""
|
||||
url = self.get_url()
|
||||
|
||||
response = self.client.get(url)
|
||||
@ -939,8 +864,7 @@ class StockTestResultTest(StockAPITestCase):
|
||||
self.assertEqual(test['user'], self.user.pk)
|
||||
|
||||
def test_post_bitmap(self):
|
||||
"""
|
||||
2021-08-25
|
||||
"""2021-08-25.
|
||||
|
||||
For some (unknown) reason, prior to fix https://github.com/inventree/InvenTree/pull/2018
|
||||
uploading a bitmap image would result in a failure.
|
||||
@ -949,7 +873,6 @@ class StockTestResultTest(StockAPITestCase):
|
||||
|
||||
As a bonus this also tests the file-upload component
|
||||
"""
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
|
||||
image_file = os.path.join(here, 'fixtures', 'test_image.bmp')
|
||||
@ -974,15 +897,12 @@ class StockTestResultTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StockAssignTest(StockAPITestCase):
|
||||
"""
|
||||
Unit tests for the stock assignment API endpoint,
|
||||
where stock items are manually assigned to a customer
|
||||
"""
|
||||
"""Unit tests for the stock assignment API endpoint, where stock items are manually assigned to a customer."""
|
||||
|
||||
URL = reverse('api-stock-assign')
|
||||
|
||||
def test_invalid(self):
|
||||
|
||||
"""Test invalid assign."""
|
||||
# Test with empty data
|
||||
response = self.post(
|
||||
self.URL,
|
||||
@ -1049,7 +969,7 @@ class StockAssignTest(StockAPITestCase):
|
||||
self.assertIn('Item must be in stock', str(response.data['items'][0]))
|
||||
|
||||
def test_valid(self):
|
||||
|
||||
"""Test valid assign."""
|
||||
stock_items = []
|
||||
|
||||
for i in range(5):
|
||||
@ -1083,14 +1003,12 @@ class StockAssignTest(StockAPITestCase):
|
||||
|
||||
|
||||
class StockMergeTest(StockAPITestCase):
|
||||
"""
|
||||
Unit tests for merging stock items via the API
|
||||
"""
|
||||
"""Unit tests for merging stock items via the API."""
|
||||
|
||||
URL = reverse('api-stock-merge')
|
||||
|
||||
def setUp(self):
|
||||
|
||||
"""Setup for all tests."""
|
||||
super().setUp()
|
||||
|
||||
self.part = part.models.Part.objects.get(pk=25)
|
||||
@ -1117,10 +1035,7 @@ class StockMergeTest(StockAPITestCase):
|
||||
)
|
||||
|
||||
def test_missing_data(self):
|
||||
"""
|
||||
Test responses which are missing required data
|
||||
"""
|
||||
|
||||
"""Test responses which are missing required data."""
|
||||
# Post completely empty
|
||||
|
||||
data = self.post(
|
||||
@ -1145,10 +1060,7 @@ class StockMergeTest(StockAPITestCase):
|
||||
self.assertIn('At least two stock items', str(data))
|
||||
|
||||
def test_invalid_data(self):
|
||||
"""
|
||||
Test responses which have invalid data
|
||||
"""
|
||||
|
||||
"""Test responses which have invalid data."""
|
||||
# Serialized stock items should be rejected
|
||||
data = self.post(
|
||||
self.URL,
|
||||
@ -1229,10 +1141,7 @@ class StockMergeTest(StockAPITestCase):
|
||||
self.assertIn('Stock items must refer to the same supplier part', str(data))
|
||||
|
||||
def test_valid_merge(self):
|
||||
"""
|
||||
Test valid merging of stock items
|
||||
"""
|
||||
|
||||
"""Test valid merging of stock items."""
|
||||
# Check initial conditions
|
||||
n = StockItem.objects.filter(part=self.part).count()
|
||||
self.assertEqual(self.item_1.quantity, 100)
|
||||
|
Reference in New Issue
Block a user