2022-06-01 15:37:39 +00:00
|
|
|
"""Unit tests for Stock views (see views.py)."""
|
2019-08-09 10:13:23 +00:00
|
|
|
|
|
|
|
from django.urls import reverse
|
2022-05-20 10:12:32 +00:00
|
|
|
|
2022-05-20 10:53:04 +00:00
|
|
|
from InvenTree.helpers import InvenTreeTestCase
|
2019-08-09 10:13:23 +00:00
|
|
|
|
2022-02-13 04:34:06 +00:00
|
|
|
# from common.models import InvenTreeSetting
|
2021-01-06 10:00:45 +00:00
|
|
|
|
2019-08-09 10:13:23 +00:00
|
|
|
|
2022-05-20 10:33:51 +00:00
|
|
|
class StockViewTestCase(InvenTreeTestCase):
|
2022-06-01 15:37:39 +00:00
|
|
|
"""Mixin for Stockview tests."""
|
2019-08-09 10:13:23 +00:00
|
|
|
|
|
|
|
fixtures = [
|
|
|
|
'category',
|
|
|
|
'part',
|
|
|
|
'company',
|
|
|
|
'location',
|
|
|
|
'supplier_part',
|
|
|
|
'stock',
|
|
|
|
]
|
|
|
|
|
2022-05-20 15:43:51 +00:00
|
|
|
roles = 'all'
|
2019-08-09 10:13:23 +00:00
|
|
|
|
2022-05-20 10:32:25 +00:00
|
|
|
|
2019-08-09 10:13:23 +00:00
|
|
|
class StockListTest(StockViewTestCase):
|
2022-06-01 15:37:39 +00:00
|
|
|
"""Tests for Stock list views."""
|
2019-08-09 10:13:23 +00:00
|
|
|
|
|
|
|
def test_stock_index(self):
|
2022-06-01 15:37:39 +00:00
|
|
|
"""Test stock index page."""
|
2019-08-09 10:13:23 +00:00
|
|
|
response = self.client.get(reverse('stock-index'))
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
|
|
|
2022-08-25 10:07:01 +00:00
|
|
|
class StockDetailTest(StockViewTestCase):
|
|
|
|
"""Unit test for the 'stock detail' page"""
|
|
|
|
|
|
|
|
def test_basic_info(self):
|
|
|
|
"""Test that basic stock item info is rendered"""
|
|
|
|
|
|
|
|
url = reverse('stock-item-detail', kwargs={'pk': 1})
|
|
|
|
|
|
|
|
response = self.client.get(url)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
|
|
|
|
html = str(response.content)
|
|
|
|
|
|
|
|
# Part name
|
|
|
|
self.assertIn('Stock Item: M2x4 LPHS', html)
|
|
|
|
|
|
|
|
# Quantity
|
|
|
|
self.assertIn('<h5>Available Quantity</h5>', html)
|
|
|
|
self.assertIn('<h5>4000 </h5>', html)
|
|
|
|
|
|
|
|
# Batch code
|
|
|
|
self.assertIn('Batch', html)
|
|
|
|
self.assertIn('<td>B123</td>', html)
|
|
|
|
|
|
|
|
# Actions to check
|
|
|
|
actions = [
|
|
|
|
"id=\\\'stock-count\\\' title=\\\'Count stock\\\'",
|
|
|
|
"id=\\\'stock-add\\\' title=\\\'Add stock\\\'",
|
|
|
|
"id=\\\'stock-remove\\\' title=\\\'Remove stock\\\'",
|
|
|
|
"id=\\\'stock-move\\\' title=\\\'Transfer stock\\\'",
|
|
|
|
"id=\\\'stock-duplicate\\\'",
|
|
|
|
"id=\\\'stock-edit\\\'",
|
|
|
|
"id=\\\'stock-delete\\\'",
|
|
|
|
]
|
|
|
|
|
|
|
|
# Initially we should not have any of the required permissions
|
|
|
|
for act in actions:
|
|
|
|
self.assertNotIn(act, html)
|
|
|
|
|
|
|
|
# Give the user all the permissions
|
|
|
|
self.assignRole('stock.add')
|
|
|
|
self.assignRole('stock.change')
|
|
|
|
self.assignRole('stock.delete')
|
|
|
|
|
|
|
|
response = self.client.get(url)
|
|
|
|
html = str(response.content)
|
|
|
|
|
|
|
|
for act in actions:
|
|
|
|
self.assertIn(act, html)
|
|
|
|
|
|
|
|
|
2020-12-03 12:32:01 +00:00
|
|
|
class StockOwnershipTest(StockViewTestCase):
|
2022-06-01 15:37:39 +00:00
|
|
|
"""Tests for stock ownership views."""
|
2020-12-03 12:32:01 +00:00
|
|
|
|
|
|
|
def setUp(self):
|
2022-06-01 15:37:39 +00:00
|
|
|
"""Add another user for ownership tests."""
|
2020-12-03 12:32:01 +00:00
|
|
|
|
2022-02-13 04:11:14 +00:00
|
|
|
"""
|
|
|
|
TODO: Refactor this following test to use the new API form
|
|
|
|
|
2020-12-03 12:32:01 +00:00
|
|
|
super().setUp()
|
|
|
|
|
2020-12-03 16:56:45 +00:00
|
|
|
# Promote existing user with staff, admin and superuser statuses
|
2020-12-03 12:32:01 +00:00
|
|
|
self.user.is_staff = True
|
2020-12-03 16:56:45 +00:00
|
|
|
self.user.is_admin = True
|
|
|
|
self.user.is_superuser = True
|
2020-12-03 12:32:01 +00:00
|
|
|
self.user.save()
|
|
|
|
|
|
|
|
# Create a new user
|
|
|
|
user = get_user_model()
|
2021-05-06 10:11:38 +00:00
|
|
|
|
2020-12-03 12:32:01 +00:00
|
|
|
self.new_user = user.objects.create_user(
|
|
|
|
username='john',
|
|
|
|
email='john@email.com',
|
|
|
|
password='custom123',
|
|
|
|
)
|
|
|
|
|
|
|
|
# Put the user into a new group with the correct permissions
|
|
|
|
group = Group.objects.create(name='new_group')
|
|
|
|
self.new_user.groups.add(group)
|
|
|
|
|
|
|
|
# Give the group *all* the permissions!
|
|
|
|
for rule in group.rule_sets.all():
|
|
|
|
rule.can_view = True
|
|
|
|
rule.can_change = True
|
|
|
|
rule.can_add = True
|
|
|
|
rule.can_delete = True
|
|
|
|
|
|
|
|
rule.save()
|
|
|
|
|
|
|
|
def enable_ownership(self):
|
|
|
|
# Enable stock location ownership
|
|
|
|
|
|
|
|
InvenTreeSetting.set_setting('STOCK_OWNERSHIP_CONTROL', True, self.user)
|
|
|
|
self.assertEqual(True, InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL'))
|
|
|
|
|
2020-12-03 16:56:45 +00:00
|
|
|
def test_owner_control(self):
|
|
|
|
# Test stock location and item ownership
|
2021-11-03 00:33:44 +00:00
|
|
|
from .models import StockLocation
|
2021-01-12 20:02:44 +00:00
|
|
|
from users.models import Owner
|
2020-12-03 16:56:45 +00:00
|
|
|
|
|
|
|
new_user_group = self.new_user.groups.all()[0]
|
2021-01-12 20:02:44 +00:00
|
|
|
new_user_group_owner = Owner.get_owner(new_user_group)
|
|
|
|
|
|
|
|
user_as_owner = Owner.get_owner(self.user)
|
|
|
|
new_user_as_owner = Owner.get_owner(self.new_user)
|
2020-12-03 16:56:45 +00:00
|
|
|
|
2020-12-03 12:32:01 +00:00
|
|
|
# Enable ownership control
|
|
|
|
self.enable_ownership()
|
2020-12-03 16:56:45 +00:00
|
|
|
|
2021-11-03 00:33:44 +00:00
|
|
|
test_location_id = 4
|
|
|
|
test_item_id = 11
|
2020-12-03 18:29:59 +00:00
|
|
|
# Set ownership on existing item (and change location)
|
2020-12-03 16:56:45 +00:00
|
|
|
response = self.client.post(reverse('stock-item-edit', args=(test_item_id,)),
|
2021-01-12 20:02:44 +00:00
|
|
|
{'part': 1, 'status': StockStatus.OK, 'owner': user_as_owner.pk},
|
2020-12-03 16:56:45 +00:00
|
|
|
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
2021-11-02 08:51:46 +00:00
|
|
|
|
2020-12-03 16:56:45 +00:00
|
|
|
self.assertContains(response, '"form_valid": true', status_code=200)
|
2021-11-03 00:33:44 +00:00
|
|
|
|
2020-12-03 16:56:45 +00:00
|
|
|
|
|
|
|
# Logout
|
|
|
|
self.client.logout()
|
2020-12-03 12:32:01 +00:00
|
|
|
|
|
|
|
# Login with new user
|
|
|
|
self.client.login(username='john', password='custom123')
|
|
|
|
|
2021-11-03 00:33:44 +00:00
|
|
|
# TODO: Refactor this following test to use the new API form
|
2020-12-03 12:32:01 +00:00
|
|
|
# Test item edit
|
2021-01-12 21:36:29 +00:00
|
|
|
response = self.client.post(reverse('stock-item-edit', args=(test_item_id,)),
|
|
|
|
{'part': 1, 'status': StockStatus.OK, 'owner': new_user_as_owner.pk},
|
|
|
|
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
2020-12-03 16:56:45 +00:00
|
|
|
|
|
|
|
# Make sure the item's owner is unchanged
|
|
|
|
item = StockItem.objects.get(pk=test_item_id)
|
2021-01-12 20:02:44 +00:00
|
|
|
self.assertEqual(item.owner, user_as_owner)
|
2020-12-03 18:29:59 +00:00
|
|
|
|
|
|
|
# Create new parent location
|
|
|
|
parent_location = {
|
|
|
|
'name': 'John Desk',
|
|
|
|
'description': 'John\'s desk',
|
2021-01-12 20:02:44 +00:00
|
|
|
'owner': new_user_group_owner.pk,
|
2020-12-03 18:29:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Retrieve created location
|
|
|
|
location_created = StockLocation.objects.get(name=new_location['name'])
|
|
|
|
|
|
|
|
# Create new item
|
|
|
|
new_item = {
|
|
|
|
'part': 25,
|
|
|
|
'location': location_created.pk,
|
|
|
|
'quantity': 123,
|
|
|
|
'status': StockStatus.OK,
|
|
|
|
}
|
|
|
|
|
|
|
|
# Try to create new item with no owner
|
2021-01-12 21:36:29 +00:00
|
|
|
response = self.client.post(reverse('stock-item-create'),
|
|
|
|
new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
|
|
|
self.assertContains(response, '"form_valid": false', status_code=200)
|
2020-12-03 18:29:59 +00:00
|
|
|
|
|
|
|
# Try to create new item with invalid owner
|
2021-01-12 21:36:29 +00:00
|
|
|
new_item['owner'] = user_as_owner.pk
|
|
|
|
response = self.client.post(reverse('stock-item-create'),
|
|
|
|
new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
|
|
|
self.assertContains(response, '"form_valid": false', status_code=200)
|
2020-12-03 18:29:59 +00:00
|
|
|
|
|
|
|
# Try to create new item with valid owner
|
2021-01-12 21:36:29 +00:00
|
|
|
new_item['owner'] = new_user_as_owner.pk
|
2020-12-03 18:29:59 +00:00
|
|
|
response = self.client.post(reverse('stock-item-create'),
|
|
|
|
new_item, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
|
|
|
self.assertContains(response, '"form_valid": true', status_code=200)
|
2021-01-12 22:11:46 +00:00
|
|
|
|
|
|
|
# Logout
|
|
|
|
self.client.logout()
|
2021-11-03 00:33:44 +00:00
|
|
|
"""
|