diff --git a/InvenTree/InvenTree/api_tester.py b/InvenTree/InvenTree/api_tester.py index a38077000a..58a1f83c43 100644 --- a/InvenTree/InvenTree/api_tester.py +++ b/InvenTree/InvenTree/api_tester.py @@ -3,6 +3,7 @@ Helper functions for performing API unit tests """ from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group from rest_framework.test import APITestCase @@ -16,8 +17,12 @@ class InvenTreeAPITestCase(APITestCase): password = 'mypassword' email = 'test@testing.com' + superuser = False auto_login = True + # Set list of roles automatically associated with the user + roles = [] + def setUp(self): super().setUp() @@ -29,12 +34,53 @@ class InvenTreeAPITestCase(APITestCase): email=self.email ) + # Create a group for the user + self.group = Group.objects.create(name='my_test_group') + self.user.groups.add(self.group) + + if self.superuser: + self.user.is_superuser = True + self.user.save() + + for role in self.roles: + self.assignRole(role) + if self.auto_login: self.client.login(username=self.username, password=self.password) - def setRoles(self, roles): + def assignRole(self, role): """ Set the user roles for the registered user """ - pass \ No newline at end of file + # role is of the format 'rule.permission' e.g. 'part.add' + + rule, perm = role.split('.') + + for ruleset in self.group.rule_sets.all(): + + if ruleset.name == rule: + + if perm == 'view': + ruleset.can_view = True + elif perm == 'change': + ruleset.can_change = True + elif perm == 'delete': + ruleset.can_delete = True + elif perm == 'add': + ruleset.can_add = True + + ruleset.save() + break + + def get(self, url, code=200): + """ + Issue a GET request + """ + + response = self.client.get(url, format='json') + + self.assertEqual(response.status_code, code) + + return response + \ No newline at end of file diff --git a/InvenTree/InvenTree/test_api.py b/InvenTree/InvenTree/test_api.py index 9035f72435..3de90a1f82 100644 --- a/InvenTree/InvenTree/test_api.py +++ b/InvenTree/InvenTree/test_api.py @@ -98,9 +98,7 @@ class APITests(InvenTreeAPITestCase): # Now log in! self.basicAuth() - response = self.client.get(url, format='json') - - self.assertEqual(response.status_code, 200) + response = self.get(url) data = response.data @@ -114,8 +112,50 @@ class APITests(InvenTreeAPITestCase): role_names = roles.keys() - # By default, no roles are assigned to the user... + # By default, 'view' permissions are provided for rule in RuleSet.RULESET_NAMES: self.assertIn(rule, role_names) - self.assertIsNone(roles[rule]) - \ No newline at end of file + + self.assertIn('view', roles[rule]) + + self.assertNotIn('add', roles[rule]) + self.assertNotIn('change', roles[rule]) + self.assertNotIn('delete', roles[rule]) + + def test_with_superuser(self): + """ + Superuser should have *all* roles assigned + """ + + self.user.is_superuser = True + self.user.save() + + self.basicAuth() + + response = self.get(reverse('api-user-roles')) + + roles = response.data['roles'] + + for rule in RuleSet.RULESET_NAMES: + self.assertIn(rule, roles.keys()) + + for perm in ['view', 'add', 'change', 'delete']: + self.assertIn(perm, roles[rule]) + + def test_with_roles(self): + """ + Assign some roles to the user + """ + + self.basicAuth() + response = self.get(reverse('api-user-roles')) + + self.assignRole('part.delete') + self.assignRole('build.change') + response = self.get(reverse('api-user-roles')) + + roles = response.data['roles'] + + # New role permissions should have been added now + self.assertIn('delete', roles['part']) + self.assertIn('change', roles['build']) diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index dfe0acc968..614383ab30 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -67,15 +67,19 @@ class RuleSet(models.Model): 'part_partparametertemplate', 'part_partparameter', 'part_partrelated', + 'part_partstar', ], 'stock_location': [ 'stock_stocklocation', + 'label_stocklocationlabel', ], 'stock': [ 'stock_stockitem', 'stock_stockitemattachment', 'stock_stockitemtracking', 'stock_stockitemtestresult', + 'report_testreport', + 'label_stockitemlabel', ], 'build': [ 'part_part', @@ -86,6 +90,7 @@ class RuleSet(models.Model): 'build_buildorderattachment', 'stock_stockitem', 'stock_stocklocation', + 'report_buildreport', ], 'purchase_order': [ 'company_company', @@ -115,14 +120,9 @@ class RuleSet(models.Model): 'common_colortheme', 'common_inventreesetting', 'company_contact', - 'label_stockitemlabel', - 'label_stocklocationlabel', 'report_reportasset', 'report_reportsnippet', - 'report_testreport', - 'report_buildreport', 'report_billofmaterialsreport', - 'part_partstar', 'users_owner', # Third-party tables