mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Added test units for migration and API
This commit is contained in:
parent
76fe535ef9
commit
7b4d3a3c07
@ -186,9 +186,6 @@ class ManufacturerPartDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
queryset = ManufacturerPart.objects.all()
|
||||
serializer_class = ManufacturerPartSerializer
|
||||
|
||||
read_only_fields = [
|
||||
]
|
||||
|
||||
|
||||
class SupplierPartList(generics.ListCreateAPIView):
|
||||
""" API endpoint for list view of SupplierPart object
|
||||
|
@ -7,62 +7,65 @@ def supplierpart_make_manufacturer_parts(apps, schema_editor):
|
||||
Part = apps.get_model('part', 'Part')
|
||||
ManufacturerPart = apps.get_model('company', 'ManufacturerPart')
|
||||
SupplierPart = apps.get_model('company', 'SupplierPart')
|
||||
|
||||
supplier_parts = SupplierPart.objects.all()
|
||||
|
||||
print(f'\nCreating Manufacturer parts\n{"-"*10}')
|
||||
for supplier_part in SupplierPart.objects.all():
|
||||
print(f'{supplier_part.supplier.name[:15].ljust(15)} | {supplier_part.SKU[:15].ljust(15)}\t', end='')
|
||||
if supplier_parts:
|
||||
print(f'\nCreating Manufacturer parts\n{"-"*10}')
|
||||
for supplier_part in supplier_parts:
|
||||
print(f'{supplier_part.supplier.name[:15].ljust(15)} | {supplier_part.SKU[:15].ljust(15)}\t', end='')
|
||||
|
||||
if supplier_part.manufacturer_part:
|
||||
print(f'[ERROR: MANUFACTURER PART ALREADY EXISTS]')
|
||||
continue
|
||||
if supplier_part.manufacturer_part:
|
||||
print(f'[ERROR: MANUFACTURER PART ALREADY EXISTS]')
|
||||
continue
|
||||
|
||||
part = supplier_part.part
|
||||
if not part:
|
||||
print(f'[ERROR: SUPPLIER PART IS NOT CONNECTED TO PART]')
|
||||
continue
|
||||
|
||||
manufacturer = supplier_part.manufacturer
|
||||
MPN = supplier_part.MPN
|
||||
link = supplier_part.link
|
||||
description = supplier_part.description
|
||||
|
||||
if manufacturer or MPN:
|
||||
print(f' | {part.name[:15].ljust(15)}', end='')
|
||||
part = supplier_part.part
|
||||
if not part:
|
||||
print(f'[ERROR: SUPPLIER PART IS NOT CONNECTED TO PART]')
|
||||
continue
|
||||
|
||||
try:
|
||||
print(f' | {manufacturer.name[:15].ljust(15)}', end='')
|
||||
except TypeError:
|
||||
print(f' | {"EMPTY MANUF".ljust(15)}', end='')
|
||||
manufacturer = supplier_part.manufacturer
|
||||
MPN = supplier_part.MPN
|
||||
link = supplier_part.link
|
||||
description = supplier_part.description
|
||||
|
||||
try:
|
||||
print(f' | {MPN[:15].ljust(15)}', end='')
|
||||
except TypeError:
|
||||
print(f' | {"EMPTY MPN".ljust(15)}', end='')
|
||||
if manufacturer or MPN:
|
||||
print(f' | {part.name[:15].ljust(15)}', end='')
|
||||
|
||||
try:
|
||||
print(f' | {manufacturer.name[:15].ljust(15)}', end='')
|
||||
except AttributeError:
|
||||
print(f' | {"EMPTY MANUF".ljust(15)}', end='')
|
||||
|
||||
print('\t', end='')
|
||||
try:
|
||||
print(f' | {MPN[:15].ljust(15)}', end='')
|
||||
except TypeError:
|
||||
print(f' | {"EMPTY MPN".ljust(15)}', end='')
|
||||
|
||||
# Create ManufacturerPart
|
||||
manufacturer_part = ManufacturerPart(part=part, manufacturer=manufacturer, MPN=MPN, description=description, link=link)
|
||||
created = False
|
||||
try:
|
||||
with transaction.atomic():
|
||||
manufacturer_part.save()
|
||||
created = True
|
||||
except IntegrityError:
|
||||
manufacturer_part = ManufacturerPart.objects.get(part=part, manufacturer=manufacturer, MPN=MPN)
|
||||
print('\t', end='')
|
||||
|
||||
# Link it to SupplierPart
|
||||
supplier_part.manufacturer_part = manufacturer_part
|
||||
supplier_part.save()
|
||||
# Create ManufacturerPart
|
||||
manufacturer_part = ManufacturerPart(part=part, manufacturer=manufacturer, MPN=MPN, description=description, link=link)
|
||||
created = False
|
||||
try:
|
||||
with transaction.atomic():
|
||||
manufacturer_part.save()
|
||||
created = True
|
||||
except IntegrityError:
|
||||
manufacturer_part = ManufacturerPart.objects.get(part=part, manufacturer=manufacturer, MPN=MPN)
|
||||
|
||||
if created:
|
||||
print(f'[SUCCESS: MANUFACTURER PART CREATED]')
|
||||
# Link it to SupplierPart
|
||||
supplier_part.manufacturer_part = manufacturer_part
|
||||
supplier_part.save()
|
||||
|
||||
if created:
|
||||
print(f'[SUCCESS: MANUFACTURER PART CREATED]')
|
||||
else:
|
||||
print(f'[IGNORED: MANUFACTURER PART ALREADY EXISTS]')
|
||||
else:
|
||||
print(f'[IGNORED: MANUFACTURER PART ALREADY EXISTS]')
|
||||
else:
|
||||
print(f'[IGNORED: MISSING MANUFACTURER DATA]')
|
||||
print(f'[IGNORED: MISSING MANUFACTURER DATA]')
|
||||
|
||||
print(f'{"-"*10}\nDone')
|
||||
print(f'{"-"*10}\nDone\n')
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -27,7 +27,7 @@ class CompanyTest(InvenTreeAPITestCase):
|
||||
def test_company_list(self):
|
||||
url = reverse('api-company-list')
|
||||
|
||||
# There should be two companies
|
||||
# There should be three companies
|
||||
response = self.get(url)
|
||||
self.assertEqual(len(response.data), 3)
|
||||
|
||||
@ -62,3 +62,64 @@ class CompanyTest(InvenTreeAPITestCase):
|
||||
data = {'search': 'cup'}
|
||||
response = self.get(url, data)
|
||||
self.assertEqual(len(response.data), 2)
|
||||
|
||||
|
||||
class ManufacturerTest(InvenTreeAPITestCase):
|
||||
"""
|
||||
Series of tests for the Manufacturer DRF API
|
||||
"""
|
||||
|
||||
fixtures = [
|
||||
'category',
|
||||
'part',
|
||||
'location',
|
||||
'company',
|
||||
'manufacturer_part',
|
||||
]
|
||||
|
||||
roles = [
|
||||
'part.change',
|
||||
]
|
||||
|
||||
def test_manufacturer_part_list(self):
|
||||
url = reverse('api-manufacturer-part-list')
|
||||
|
||||
# There should be three manufacturer parts
|
||||
response = self.get(url)
|
||||
self.assertEqual(len(response.data), 3)
|
||||
|
||||
# Filter by manufacturer
|
||||
data = {'company': 7}
|
||||
response = self.get(url, data)
|
||||
self.assertEqual(len(response.data), 2)
|
||||
|
||||
# Filter by part
|
||||
data = {'part': 5}
|
||||
response = self.get(url, data)
|
||||
self.assertEqual(len(response.data), 2)
|
||||
|
||||
# Filter by supplier part (should return only one manufacturer part)
|
||||
data = {'supplier_part': 10}
|
||||
response = self.get(url, data)
|
||||
self.assertEqual(len(response.data), 1)
|
||||
|
||||
def test_manufacturer_part_detail(self):
|
||||
url = reverse('api-manufacturer-part-detail', kwargs={'pk': 1})
|
||||
response = self.get(url)
|
||||
|
||||
self.assertEqual(response.data['MPN'], 'MPN123')
|
||||
|
||||
# Change the MPN
|
||||
data = {
|
||||
'MPN': 'MPN-TEST-123',
|
||||
}
|
||||
response = self.client.patch(url, data, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data['MPN'], 'MPN-TEST-123')
|
||||
|
||||
def test_manufacturer_part_search(self):
|
||||
# Test search functionality in manufacturer list
|
||||
url = reverse('api-manufacturer-part-list')
|
||||
data = {'search': 'MPN'}
|
||||
response = self.get(url, data)
|
||||
self.assertEqual(len(response.data), 3)
|
||||
|
@ -79,7 +79,7 @@ class TestManufacturerField(MigratorTestCase):
|
||||
part=part,
|
||||
supplier=supplier,
|
||||
SKU='SCREW.002',
|
||||
manufacturer_name='Zero Corp'
|
||||
manufacturer_name='Zero Corp',
|
||||
)
|
||||
|
||||
self.assertEqual(Company.objects.count(), 1)
|
||||
@ -107,6 +107,136 @@ class TestManufacturerField(MigratorTestCase):
|
||||
self.assertEqual(part.manufacturer.name, 'ACME')
|
||||
|
||||
|
||||
class TestManufacturerPart(MigratorTestCase):
|
||||
"""
|
||||
Tests for migration 0032 and 0033 which added ManufacturerPart model
|
||||
"""
|
||||
|
||||
migrate_from = ('company', '0031_auto_20210103_2215')
|
||||
migrate_to = ('company', '0033_supplierpart_update')
|
||||
|
||||
def prepare(self):
|
||||
"""
|
||||
Prepare the database by adding some test data 'before' the change:
|
||||
|
||||
- Part object
|
||||
- Company object (supplier)
|
||||
- SupplierPart object
|
||||
"""
|
||||
|
||||
Part = self.old_state.apps.get_model('part', 'part')
|
||||
Company = self.old_state.apps.get_model('company', 'company')
|
||||
SupplierPart = self.old_state.apps.get_model('company', 'supplierpart')
|
||||
|
||||
# Create an initial part
|
||||
part = Part.objects.create(
|
||||
name='CAP CER 0.1UF 10V X5R 0402',
|
||||
description='CAP CER 0.1UF 10V X5R 0402',
|
||||
purchaseable=True,
|
||||
level=0,
|
||||
tree_id=0,
|
||||
lft=0,
|
||||
rght=0,
|
||||
)
|
||||
|
||||
# Create a manufacturer
|
||||
manufacturer = Company.objects.create(
|
||||
name='Murata',
|
||||
description='Makes capacitors',
|
||||
is_manufacturer=True,
|
||||
is_supplier=False,
|
||||
is_customer=False,
|
||||
)
|
||||
|
||||
# Create suppliers
|
||||
supplier_1 = Company.objects.create(
|
||||
name='Digi-Key',
|
||||
description='A supplier of components',
|
||||
is_manufacturer=False,
|
||||
is_supplier=True,
|
||||
is_customer=False,
|
||||
)
|
||||
|
||||
supplier_2 = Company.objects.create(
|
||||
name='Mouser',
|
||||
description='We sell components',
|
||||
is_manufacturer=False,
|
||||
is_supplier=True,
|
||||
is_customer=False,
|
||||
)
|
||||
|
||||
# Add some SupplierPart objects
|
||||
SupplierPart.objects.create(
|
||||
part=part,
|
||||
supplier=supplier_1,
|
||||
SKU='DK-MUR-CAP-123456-ND',
|
||||
manufacturer=manufacturer,
|
||||
MPN='MUR-CAP-123456',
|
||||
)
|
||||
|
||||
SupplierPart.objects.create(
|
||||
part=part,
|
||||
supplier=supplier_1,
|
||||
SKU='DK-MUR-CAP-987654-ND',
|
||||
manufacturer=manufacturer,
|
||||
MPN='MUR-CAP-987654',
|
||||
)
|
||||
|
||||
SupplierPart.objects.create(
|
||||
part=part,
|
||||
supplier=supplier_2,
|
||||
SKU='CAP-CER-01UF',
|
||||
manufacturer=manufacturer,
|
||||
MPN='MUR-CAP-123456',
|
||||
)
|
||||
|
||||
# No MPN
|
||||
SupplierPart.objects.create(
|
||||
part=part,
|
||||
supplier=supplier_2,
|
||||
SKU='CAP-CER-01UF-1',
|
||||
manufacturer=manufacturer,
|
||||
)
|
||||
|
||||
# No Manufacturer
|
||||
SupplierPart.objects.create(
|
||||
part=part,
|
||||
supplier=supplier_2,
|
||||
SKU='CAP-CER-01UF-2',
|
||||
MPN='MUR-CAP-123456',
|
||||
)
|
||||
|
||||
# No Manufacturer data
|
||||
SupplierPart.objects.create(
|
||||
part=part,
|
||||
supplier=supplier_2,
|
||||
SKU='CAP-CER-01UF-3',
|
||||
)
|
||||
|
||||
def test_manufacturer_part_objects(self):
|
||||
"""
|
||||
Test that the new companies have been created successfully
|
||||
"""
|
||||
|
||||
# Check on the SupplierPart objects
|
||||
SupplierPart = self.new_state.apps.get_model('company', 'supplierpart')
|
||||
|
||||
supplier_parts = SupplierPart.objects.all()
|
||||
self.assertEqual(supplier_parts.count(), 6)
|
||||
|
||||
supplier_parts = SupplierPart.objects.filter(supplier__name='Mouser')
|
||||
self.assertEqual(supplier_parts.count(), 4)
|
||||
|
||||
# Check on the ManufacturerPart objects
|
||||
ManufacturerPart = self.new_state.apps.get_model('company', 'manufacturerpart')
|
||||
|
||||
manufacturer_parts = ManufacturerPart.objects.all()
|
||||
self.assertEqual(manufacturer_parts.count(), 4)
|
||||
|
||||
manufacturer_part = manufacturer_parts.first()
|
||||
self.assertEqual(manufacturer_part.MPN, 'MUR-CAP-123456')
|
||||
|
||||
|
||||
class TestCurrencyMigration(MigratorTestCase):
|
||||
"""
|
||||
Tests for upgrade from basic currency support to django-money
|
||||
|
@ -220,7 +220,7 @@ class ManufacturerPartViewTests(CompanyViewTestBase):
|
||||
response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# How many supplier parts are already in the database?
|
||||
# How many manufaturer parts are already in the database?
|
||||
n = ManufacturerPart.objects.all().count()
|
||||
|
||||
data = {
|
||||
@ -240,6 +240,41 @@ class ManufacturerPartViewTests(CompanyViewTestBase):
|
||||
# Check that the ManufacturerPart was created!
|
||||
self.assertEqual(n + 1, ManufacturerPart.objects.all().count())
|
||||
|
||||
# Try to create duplicate ManufacturerPart
|
||||
(response, errors) = self.post(url, data, valid=False)
|
||||
|
||||
self.assertIsNotNone(errors.get('__all__', None))
|
||||
|
||||
# Check that the ManufacturerPart count stayed the same
|
||||
self.assertEqual(n + 1, ManufacturerPart.objects.all().count())
|
||||
|
||||
def test_supplier_part_create(self):
|
||||
"""
|
||||
Test that the SupplierPartCreate view creates Manufacturer Part.
|
||||
"""
|
||||
|
||||
url = reverse('supplier-part-create')
|
||||
|
||||
# First check that we can GET the form
|
||||
response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# How many manufacturer parts are already in the database?
|
||||
n = ManufacturerPart.objects.all().count()
|
||||
|
||||
data = {
|
||||
'part': 1,
|
||||
'supplier': 1,
|
||||
'SKU': 'SKU_TEST',
|
||||
'manufacturer': 6,
|
||||
'MPN': 'MPN_TEST',
|
||||
}
|
||||
|
||||
(response, errors) = self.post(url, data, valid=True)
|
||||
|
||||
# Check that the ManufacturerPart was created!
|
||||
self.assertEqual(n + 1, ManufacturerPart.objects.all().count())
|
||||
|
||||
def test_manufacturer_part_delete(self):
|
||||
"""
|
||||
Test the ManufacturerPartDelete view
|
||||
@ -248,11 +283,13 @@ class ManufacturerPartViewTests(CompanyViewTestBase):
|
||||
url = reverse('manufacturer-part-delete')
|
||||
|
||||
# Get form using 'part' argument
|
||||
response = self.client.get(url, {'part': '5'}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
response = self.client.get(url, {'part': '2'}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# POST to delete manufacturer part
|
||||
n = ManufacturerPart.objects.count()
|
||||
m = SupplierPart.objects.count()
|
||||
|
||||
response = self.client.post(
|
||||
url,
|
||||
{
|
||||
@ -263,4 +300,7 @@ class ManufacturerPartViewTests(CompanyViewTestBase):
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Check that the ManufacturerPart was deleted
|
||||
self.assertEqual(n - 1, ManufacturerPart.objects.count())
|
||||
# Check that the SupplierParts were deleted
|
||||
self.assertEqual(m - 2, SupplierPart.objects.count())
|
||||
|
Loading…
Reference in New Issue
Block a user