CI: Add pre-commit hook to use modern testing asserts (#7126)

* Add test to ensure modern testing syntax is used

* auto-fixes for testing formats

* remove usage of depreceated assertDictContainsSubset
This commit is contained in:
Matthias Mair 2024-04-29 00:17:54 +02:00 committed by GitHub
parent d2827df3b8
commit b711291beb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 115 additions and 101 deletions

View File

@ -84,3 +84,7 @@ repos:
# rev: 3.0.0
# hooks:
# - id: shellcheck
- repo: https://github.com/isidentical/teyit
rev: 0.4.3
hooks:
- id: teyit

View File

@ -128,7 +128,7 @@ class APITests(InvenTreeAPITestCase):
response = self.client.get(url, format='json')
# Not logged in, so cannot access user role data
self.assertTrue(response.status_code in [401, 403])
self.assertIn(response.status_code, [401, 403])
# Now log in!
self.basicAuth()

View File

@ -1030,7 +1030,7 @@ class TestVersionNumber(TestCase):
s = '.'.join([str(i) for i in v])
self.assertTrue(s in version.inventreeVersion())
self.assertIn(s, version.inventreeVersion())
def test_comparison(self):
"""Test direct comparison of version numbers."""
@ -1039,10 +1039,10 @@ class TestVersionNumber(TestCase):
v_c = version.inventreeVersionTuple('1.2.4')
v_d = version.inventreeVersionTuple('2.0.0')
self.assertTrue(v_b > v_a)
self.assertTrue(v_c > v_b)
self.assertTrue(v_d > v_c)
self.assertTrue(v_d > v_a)
self.assertGreater(v_b, v_a)
self.assertGreater(v_c, v_b)
self.assertGreater(v_d, v_c)
self.assertGreater(v_d, v_a)
def test_commit_info(self):
"""Test that the git commit information is extracted successfully."""
@ -1505,7 +1505,7 @@ class MagicLoginTest(InvenTreeTestCase):
self.assertEqual(mail.outbox[0].subject, '[InvenTree] Log in to the app')
# Check that the token is in the email
self.assertTrue('http://testserver/api/email/login/' in mail.outbox[0].body)
self.assertIn('http://testserver/api/email/login/', mail.outbox[0].body)
token = mail.outbox[0].body.split('/')[-1].split('\n')[0][8:]
self.assertEqual(get_user(token), self.user)

View File

@ -397,7 +397,7 @@ class InvenTreeAPITestCase(ExchangeRateMixin, UserMixin, APITestCase):
):
"""Helper function to process and validate a downloaded csv file."""
# Check that the correct object type has been passed
self.assertTrue(isinstance(file_object, io.StringIO))
self.assertIsInstance(file_object, io.StringIO)
file_object.seek(0)

View File

@ -247,7 +247,7 @@ class BuildTest(BuildAPITest):
expected_code=400
)
self.assertTrue('accept_unallocated' in response.data)
self.assertIn('accept_unallocated', response.data)
# Accept unallocated stock
self.post(
@ -934,7 +934,7 @@ class BuildOverallocationTest(BuildAPITest):
{},
expected_code=400
)
self.assertTrue('accept_overallocated' in response.data)
self.assertIn('accept_overallocated', response.data)
# Check stock items have not reduced at all
for si, oq, _ in self.state.values():

View File

@ -50,7 +50,7 @@ class SettingsTest(InvenTreeTestCase):
# There should be two settings objects in the database
settings = InvenTreeSetting.objects.all()
self.assertTrue(settings.count() >= 2)
self.assertGreaterEqual(settings.count(), 2)
instance_name = InvenTreeSetting.objects.get(pk=1)
self.assertEqual(instance_name.key, 'INVENTREE_INSTANCE')
@ -207,7 +207,7 @@ class SettingsTest(InvenTreeTestCase):
- Ensure that every setting key is valid
- Ensure that a validator is supplied
"""
self.assertTrue(type(setting) is dict)
self.assertIs(type(setting), dict)
name = setting.get('name', None)
@ -726,7 +726,7 @@ class TaskListApiTests(InvenTreeAPITestCase):
response = self.get(url, expected_code=200)
for task in response.data:
self.assertTrue(task['name'] == 'time.sleep')
self.assertEqual(task['name'], 'time.sleep')
class WebhookMessageTests(TestCase):

View File

@ -130,7 +130,7 @@ class CompanyTest(InvenTreeAPITestCase):
expected_code=400,
)
self.assertTrue('currency' in response.data)
self.assertIn('currency', response.data)
def test_company_active(self):
"""Test that the 'active' value and filter works."""

View File

@ -36,18 +36,18 @@ class LabelTest(InvenTreeAPITestCase):
"""Test that the default label templates are copied across."""
labels = StockItemLabel.objects.all()
self.assertTrue(labels.count() > 0)
self.assertGreater(labels.count(), 0)
labels = StockLocationLabel.objects.all()
self.assertTrue(labels.count() > 0)
self.assertGreater(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)
self.assertGreater(len([item_dir.iterdir()]), 0)
test_subdir('stockitem')
test_subdir('stocklocation')

View File

@ -80,15 +80,18 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase):
machine_type = [t for t in response.data if t['slug'] == 'label-printer']
self.assertEqual(len(machine_type), 1)
machine_type = machine_type[0]
self.assertDictContainsSubset(
{
'slug': 'label-printer',
'name': 'Label Printer',
'description': 'Directly print labels for various items.',
'provider_plugin': None,
'is_builtin': True,
},
self.assertEqual(
machine_type,
{
**machine_type,
**{
'slug': 'label-printer',
'name': 'Label Printer',
'description': 'Directly print labels for various items.',
'provider_plugin': None,
'is_builtin': True,
},
},
)
self.assertTrue(
machine_type['provider_file'].endswith(
@ -102,17 +105,20 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase):
driver = [a for a in response.data if a['slug'] == 'test-label-printer-api']
self.assertEqual(len(driver), 1)
driver = driver[0]
self.assertDictContainsSubset(
{
'slug': 'test-label-printer-api',
'name': 'Test label printer',
'description': 'This is a test label printer driver for testing.',
'provider_plugin': None,
'is_builtin': True,
'machine_type': 'label-printer',
'driver_errors': [],
},
self.assertEqual(
driver,
{
**driver,
**{
'slug': 'test-label-printer-api',
'name': 'Test label printer',
'description': 'This is a test label printer driver for testing.',
'provider_plugin': None,
'is_builtin': True,
'machine_type': 'label-printer',
'driver_errors': [],
},
},
)
self.assertEqual(driver['provider_file'], __file__)
@ -163,19 +169,22 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase):
response = self.get(reverse('api-machine-list'))
self.assertEqual(len(response.data), 1)
self.assertDictContainsSubset(
{
'name': 'Test Machine',
'machine_type': 'label-printer',
'driver': 'test-label-printer-api',
'initialized': True,
'active': True,
'status': 101,
'status_model': 'LabelPrinterStatus',
'status_text': '',
'is_driver_available': True,
},
self.assertEqual(
response.data[0],
{
**response.data[0],
**{
'name': 'Test Machine',
'machine_type': 'label-printer',
'driver': 'test-label-printer-api',
'initialized': True,
'active': True,
'status': 101,
'status_model': 'LabelPrinterStatus',
'status_text': '',
'is_driver_available': True,
},
},
)
def test_machine_detail(self):
@ -195,19 +204,21 @@ class MachineAPITest(TestMachineRegistryMixin, InvenTreeAPITestCase):
# Create a machine
response = self.post(reverse('api-machine-list'), machine_data)
self.assertDictContainsSubset(machine_data, response.data)
self.assertEqual(response.data, {**response.data, **machine_data})
pk = response.data['pk']
# Retrieve the machine
response = self.get(reverse('api-machine-detail', kwargs={'pk': pk}))
self.assertDictContainsSubset(machine_data, response.data)
self.assertEqual(response.data, {**response.data, **machine_data})
# Update the machine
response = self.patch(
reverse('api-machine-detail', kwargs={'pk': pk}),
{'name': 'Updated Machine'},
)
self.assertDictContainsSubset({'name': 'Updated Machine'}, response.data)
self.assertEqual(
response.data, {**response.data, **{'name': 'Updated Machine'}}
)
self.assertEqual(MachineConfig.objects.get(pk=pk).name, 'Updated Machine')
# Delete the machine

View File

@ -418,7 +418,7 @@ class PurchaseOrderTest(OrderTest):
po = models.PurchaseOrder.objects.get(pk=1)
self.assertTrue(po.lines.count() > 0)
self.assertGreater(po.lines.count(), 0)
lines = []
@ -839,7 +839,7 @@ class PurchaseOrderDownloadTest(OrderTest):
expected_code=200,
expected_fn='InvenTree_PurchaseOrderItems.xlsx',
) as file:
self.assertTrue(isinstance(file, io.BytesIO))
self.assertIsInstance(file, io.BytesIO)
class PurchaseOrderReceiveTest(OrderTest):
@ -1570,7 +1570,7 @@ class SalesOrderDownloadTest(OrderTest):
expected_fn='InvenTree_SalesOrders.xls',
decode=False,
) as file:
self.assertTrue(isinstance(file, io.BytesIO))
self.assertIsInstance(file, io.BytesIO)
def test_download_csv(self):
"""Test that the list of sales orders can be downloaded as a .csv file."""
@ -1772,7 +1772,7 @@ class SalesOrderAllocateTest(OrderTest):
# At least one item should be allocated, and all should be variants
self.assertGreater(self.order.stock_allocations.count(), 0)
for allocation in self.order.stock_allocations.all():
self.assertNotEquals(allocation.item.part.pk, allocation.line.part.pk)
self.assertNotEqual(allocation.item.part.pk, allocation.line.part.pk)
def test_shipment_complete(self):
"""Test that we can complete a shipment via the API."""

View File

@ -463,12 +463,12 @@ class PartCategoryAPITest(InvenTreeAPITestCase):
response = self.get(url, {'path_detail': False}, expected_code=200)
# Check that the path detail information is not included
self.assertFalse('path' in response.data.keys())
self.assertNotIn('path', response.data.keys())
# Now, request *with* path detail
response = self.get(url, {'path_detail': True}, expected_code=200)
self.assertTrue('path' in response.data.keys())
self.assertIn('path', response.data.keys())
path = response.data['path']
@ -520,7 +520,7 @@ class PartOptionsAPITest(InvenTreeAPITestCase):
# Check that a bunch o' fields are contained
for f in ['assembly', 'component', 'description', 'image', 'IPN']:
self.assertTrue(f in actions.keys())
self.assertIn(f, actions.keys())
# Active is a 'boolean' field
active = actions['active']
@ -553,7 +553,7 @@ class PartOptionsAPITest(InvenTreeAPITestCase):
actions = self.getActions(reverse('api-part-category-list'))
# actions should *not* contain 'POST' as we do not have the correct role
self.assertFalse('POST' in actions)
self.assertNotIn('POST', actions)
self.assignRole('part_category.add')
@ -1055,8 +1055,8 @@ class PartAPITest(PartAPITestBase):
# Filter by creation date
response = self.get(url, {'created_before': '2019-01-01'}, expected_code=200)
self.assertTrue(len(response.data) < n)
self.assertTrue(len(response.data) > 0)
self.assertLess(len(response.data), n)
self.assertGreater(len(response.data), 0)
for item in response.data:
self.assertIsNotNone(item['creation_date'])
@ -1066,8 +1066,8 @@ class PartAPITest(PartAPITestBase):
response = self.get(url, {'created_after': '2019-01-01'}, expected_code=200)
self.assertTrue(len(response.data) < n)
self.assertTrue(len(response.data) > 0)
self.assertLess(len(response.data), n)
self.assertGreater(len(response.data), 0)
for item in response.data:
self.assertIsNotNone(item['creation_date'])
@ -2153,7 +2153,7 @@ class BomItemTest(InvenTreeAPITestCase):
response = self.get(url, data={'validated': False}, expected_code=200)
# There should be at least one non-validated item
self.assertTrue(len(response.data) > 0)
self.assertGreater(len(response.data), 0)
# Now, let's validate an item
bom_item = BomItem.objects.first()
@ -2169,7 +2169,7 @@ class BomItemTest(InvenTreeAPITestCase):
# Each item in response should contain expected keys
for el in response.data:
for key in ['available_stock', 'available_substitute_stock']:
self.assertTrue(key in el)
self.assertIn(key, el)
def test_bom_list_search(self):
"""Test that we can search the BOM list API endpoint."""
@ -2208,7 +2208,7 @@ class BomItemTest(InvenTreeAPITestCase):
q1 = response.data[0]['quantity']
q2 = response.data[-1]['quantity']
self.assertTrue(q1 < q2)
self.assertLess(q1, q2)
# Order by decreasing quantity
response = self.get(f'{url}?ordering=-quantity', expected_code=200)
@ -2255,7 +2255,7 @@ class BomItemTest(InvenTreeAPITestCase):
]
for key in expected_values:
self.assertTrue(key in response.data)
self.assertIn(key, response.data)
self.assertEqual(int(float(response.data['quantity'])), 25)

View File

@ -117,7 +117,7 @@ class CategoryTest(TestCase):
child.pathstring,
'Cat/AAAAAAAAAA/BBBBBBBBBB/CCCCCCCCCC/DDDDDDDDDD/EEEEEEEEEE/FFFFFFFFFF/GGGGGGGGGG/HHHHHHHHHH/IIIIIIIIII/JJJJJJJJJJ/KKKKKKKKK...OO/PPPPPPPPPP/QQQQQQQQQQ/RRRRRRRRRR/SSSSSSSSSS/TTTTTTTTTT/UUUUUUUUUU/VVVVVVVVVV/WWWWWWWWWW/XXXXXXXXXX/YYYYYYYYYY/ZZZZZZZZZZ',
)
self.assertTrue(len(child.pathstring) <= 250)
self.assertLessEqual(len(child.pathstring), 250)
# Attempt an invalid move
with self.assertRaises(ValidationError):
@ -325,7 +325,7 @@ class CategoryTest(TestCase):
self.assertEqual(descendants.count(), 3)
for loc in [C11, C12, C13]:
self.assertTrue(loc in descendants)
self.assertIn(loc, descendants)
# Check category C1x, should be B1 -> C1x
for loc in [C11, C12, C13]:

View File

@ -351,7 +351,7 @@ class PanelMixinTests(InvenTreeTestCase):
"""Test that the sample panel plugin is installed."""
plugins = registry.with_mixin('panel')
self.assertTrue(len(plugins) == 0)
self.assertEqual(len(plugins), 0)
# Now enable the plugin
registry.set_plugin_state('samplepanel', True)

View File

@ -196,7 +196,7 @@ class LabelMixinTests(InvenTreeAPITestCase):
options = self.options(
self.do_url(parts, plugin_ref, label), expected_code=200
).json()
self.assertTrue('amount' in options['actions']['POST'])
self.assertIn('amount', options['actions']['POST'])
plg = registry.get_plugin(plugin_ref)
with mock.patch.object(plg, 'print_label') as print_label:
@ -206,7 +206,7 @@ class LabelMixinTests(InvenTreeAPITestCase):
data={'amount': '-no-valid-int-'},
expected_code=400,
).json()
self.assertTrue('amount' in res)
self.assertIn('amount', res)
print_label.assert_not_called()
# correct value type

View File

@ -26,9 +26,9 @@ class LocatePluginTests(InvenTreeAPITestCase):
"""Test that a locate plugin is actually installed."""
plugins = registry.with_mixin('locate')
self.assertTrue(len(plugins) > 0)
self.assertGreater(len(plugins), 0)
self.assertTrue('samplelocate' in [p.slug for p in plugins])
self.assertIn('samplelocate', [p.slug for p in plugins])
def test_locate_fail(self):
"""Test various API failure modes."""

View File

@ -196,8 +196,9 @@ class PluginDetailAPITest(PluginMixin, InvenTreeAPITestCase):
mixin_dict = plg.mixins()
self.assertIn('base', mixin_dict)
self.assertDictContainsSubset(
{'base': {'key': 'base', 'human_name': 'base'}}, mixin_dict
self.assertEqual(
mixin_dict,
{**mixin_dict, **{'base': {'key': 'base', 'human_name': 'base'}}},
)
# check reload on save

View File

@ -22,5 +22,5 @@ class HelperTests(TestCase):
response = render_template(
ErrorSource(), 'sample/wrongsample.html', {'abc': 123}
)
self.assertTrue('lert alert-block alert-danger' in response)
self.assertTrue('Template file <em>sample/wrongsample.html</em>' in response)
self.assertIn('lert alert-block alert-danger', response)
self.assertIn('Template file <em>sample/wrongsample.html</em>', response)

View File

@ -275,13 +275,13 @@ class RegistryTests(TestCase):
self.assertEqual(len(registry.errors), 3)
# There should be at least one discovery error in the module `broken_file`
self.assertTrue(len(registry.errors.get('discovery')) > 0)
self.assertGreater(len(registry.errors.get('discovery')), 0)
self.assertEqual(
registry.errors.get('discovery')[0]['broken_file'],
"name 'bb' is not defined",
)
# There should be at least one load error with an intentional KeyError
self.assertTrue(len(registry.errors.get('load')) > 0)
self.assertGreater(len(registry.errors.get('load')), 0)
self.assertEqual(
registry.errors.get('load')[0]['broken_sample'], "'This is a dummy error'"
)

View File

@ -194,19 +194,19 @@ class BarcodeTagTest(TestCase):
"""Test the barcode generation tag."""
barcode = barcode_tags.barcode('12345')
self.assertTrue(isinstance(barcode, str))
self.assertIsInstance(barcode, str)
self.assertTrue(barcode.startswith('data:image/png;'))
# Try with a different format
barcode = barcode_tags.barcode('99999', format='BMP')
self.assertTrue(isinstance(barcode, str))
self.assertIsInstance(barcode, str)
self.assertTrue(barcode.startswith('data:image/bmp;'))
def test_qrcode(self):
"""Test the qrcode generation tag."""
# Test with default settings
qrcode = barcode_tags.qrcode('hello world')
self.assertTrue(isinstance(qrcode, str))
self.assertIsInstance(qrcode, str)
self.assertTrue(qrcode.startswith('data:image/png;'))
self.assertEqual(len(qrcode), 700)
@ -214,7 +214,7 @@ class BarcodeTagTest(TestCase):
qrcode = barcode_tags.qrcode(
'hello_world', version=2, box_size=50, format='BMP'
)
self.assertTrue(isinstance(qrcode, str))
self.assertIsInstance(qrcode, str)
self.assertTrue(qrcode.startswith('data:image/bmp;'))
self.assertEqual(len(qrcode), 309720)

View File

@ -552,7 +552,7 @@ class StockItemListTest(StockAPITestCase):
response = self.get(
self.list_url, {'location': 'null', 'cascade': False}, expected_code=200
)
self.assertTrue(len(response.data) < StockItem.objects.count())
self.assertLess(len(response.data), StockItem.objects.count())
# Filter with "cascade=True"
response = self.get(
@ -662,10 +662,10 @@ class StockItemListTest(StockAPITestCase):
self.assertEqual(n_stock_items, len(with_batch) + len(without_batch))
for item in with_batch:
self.assertFalse(item['batch'] in [None, ''])
self.assertNotIn(item['batch'], [None, ''])
for item in without_batch:
self.assertTrue(item['batch'] in [None, ''])
self.assertIn(item['batch'], [None, ''])
def test_filter_by_tracked(self):
"""Test the 'tracked' filter.
@ -746,9 +746,7 @@ class StockItemListTest(StockAPITestCase):
self.assertEqual(response.status_code, 200)
self.assertTrue(
isinstance(response, django.http.response.StreamingHttpResponse)
)
self.assertIsInstance(response, django.http.response.StreamingHttpResponse)
file_object = io.StringIO(response.getvalue().decode('utf-8'))
@ -1132,7 +1130,7 @@ class StockItemTest(StockAPITestCase):
# Check that each serial number was created
for i in range(1, 11):
self.assertTrue(str(i) in sn)
self.assertIn(str(i), sn)
# Check the unique stock item has been created

View File

@ -182,13 +182,13 @@ class OwnerModelTest(InvenTreeTestCase):
# Get related owners (user + group)
related_owners = group_as_owner.get_related_owners(include_group=True)
self.assertTrue(user_as_owner in related_owners)
self.assertTrue(group_as_owner in related_owners)
self.assertIn(user_as_owner, related_owners)
self.assertIn(group_as_owner, related_owners)
# Get related owners (only user)
related_owners = group_as_owner.get_related_owners(include_group=False)
self.assertTrue(user_as_owner in related_owners)
self.assertFalse(group_as_owner in related_owners)
self.assertIn(user_as_owner, related_owners)
self.assertNotIn(group_as_owner, related_owners)
# Get related owners on user
related_owners = user_as_owner.get_related_owners()

View File

@ -18,10 +18,10 @@ class TemplateTagTest(InvenTreeTestCase):
def assertSettings(self, settings_data):
"""Helper to test if needed args are in the settings."""
self.assertTrue('debug' in settings_data)
self.assertTrue('server_list' in settings_data)
self.assertTrue('show_server_selector' in settings_data)
self.assertTrue('environment' in settings_data)
self.assertIn('debug', settings_data)
self.assertIn('server_list', settings_data)
self.assertIn('show_server_selector', settings_data)
self.assertIn('environment', settings_data)
def test_spa_bundle(self):
"""Test the 'spa_bundle' template tag."""
@ -32,8 +32,8 @@ class TemplateTagTest(InvenTreeTestCase):
return # pragma: no cover
shipped_js = resp.split('<script type="module" src="')[1:]
self.assertTrue(len(shipped_js) > 0)
self.assertTrue(len(shipped_js) == 3)
self.assertGreater(len(shipped_js), 0)
self.assertEqual(len(shipped_js), 3)
manifest_file = Path(__file__).parent.joinpath('static/web/.vite/manifest.json')
# Try with removed manifest file
@ -75,7 +75,7 @@ class TemplateTagTest(InvenTreeTestCase):
envs = {'INVENTREE_PUI_SETTINGS': json.dumps({'server_list': ['aa', 'bb']})}
with mock.patch.dict(os.environ, envs):
rsp = get_frontend_settings(False)
self.assertFalse('show_server_selector' in rsp)
self.assertNotIn('show_server_selector', rsp)
self.assertEqual(rsp['server_list'], ['aa', 'bb'])