diff --git a/InvenTree/InvenTree/test_api.py b/InvenTree/InvenTree/test_api.py new file mode 100644 index 0000000000..0bb36db59f --- /dev/null +++ b/InvenTree/InvenTree/test_api.py @@ -0,0 +1,67 @@ +""" Low level tests for the InvenTree API """ + +from rest_framework.test import APITestCase +from rest_framework import status + +from django.urls import reverse + +from django.contrib.auth import get_user_model + + +class APITests(APITestCase): + """ Tests for the InvenTree API """ + + fixtures = [ + 'location', + 'stock', + 'part', + 'category', + ] + + username = 'test_user' + password = 'test_pass' + + def setUp(self): + + # Create a user (but do not log in!) + User = get_user_model() + User.objects.create_user(self.username, 'user@email.com', self.password) + + def test_get_token_fail(self): + """ Ensure that an invalid user cannot get a token """ + + token_url = reverse('api-token') + + response = self.client.post(token_url, format='json', data={'username': 'bad', 'password': 'also_bad'}) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertFalse('token' in response.data) + + def test_get_token_pass(self): + """ Ensure that a valid user can request an API token """ + + token_url = reverse('api-token') + + # POST to retreive a token + response = self.client.post(token_url, format='json', data={'username': self.username, 'password': self.password}) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue('token' in response.data) + self.assertTrue('pk' in response.data) + self.assertTrue(len(response.data['token']) > 0) + + # Now, use the token to access other data + token = response.data['token'] + + part_url = reverse('api-part-list') + + # Try to access without a token + response = self.client.get(part_url, format='json') + + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + # Now, with the token + self.client.credentials(HTTP_AUTHORIZATION='Token ' + token) + response = self.client.get(part_url, format='json') + + self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/InvenTree/InvenTree/test_views.py b/InvenTree/InvenTree/test_views.py index 150a6a4f30..171dcbb05f 100644 --- a/InvenTree/InvenTree/test_views.py +++ b/InvenTree/InvenTree/test_views.py @@ -10,13 +10,16 @@ import os class ViewTests(TestCase): """ Tests for various top-level views """ + username = 'test_user' + password = 'test_pass' + def setUp(self): # Create a user User = get_user_model() - User.objects.create_user('username', 'user@email.com', 'password') + User.objects.create_user(self.username, 'user@email.com', self.password) - self.client.login(username='username', password='password') + self.client.login(username=self.username, password=self.password) def test_api_doc(self): """ Test that the api-doc view works """ diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index de3b9bab2c..61bb9ec138 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -69,7 +69,7 @@ class Currency(models.Model): cur.save() # If there are no currencies set as the base currency, set this as base - if not Currency.objects.filter(base=True).exists(): + if not Currency.objects.exclude(pk=self.pk).filter(base=True).exists(): self.base = True # If this is the base currency, ensure value is set to unity diff --git a/InvenTree/templates/InvenTree/settings/currency.html b/InvenTree/templates/InvenTree/settings/currency.html index 2c7b3dbccb..712cd1700c 100644 --- a/InvenTree/templates/InvenTree/settings/currency.html +++ b/InvenTree/templates/InvenTree/settings/currency.html @@ -60,6 +60,13 @@ field: 'value', title: 'Value', sortable: true, + formatter: function(value, row, index, field) { + if (row.base) { + return "Base Currency"; + } else { + return value; + } + } }, { formatter: function(value, row, index, field) { diff --git a/InvenTree/users/urls.py b/InvenTree/users/urls.py index 6082ef14df..312789b55b 100644 --- a/InvenTree/users/urls.py +++ b/InvenTree/users/urls.py @@ -5,7 +5,7 @@ from . import views user_urls = [ url(r'^(?P[0-9]+)/?$', views.UserDetail.as_view(), name='user-detail'), - url(r'token', views.GetAuthToken.as_view()), + url(r'token', views.GetAuthToken.as_view(), name='api-token'), url(r'^$', views.UserList.as_view()), ] diff --git a/Makefile b/Makefile index aaf795144e..7ea3f33b03 100644 --- a/Makefile +++ b/Makefile @@ -15,10 +15,11 @@ migrate: python3 InvenTree/manage.py makemigrations stock python3 InvenTree/manage.py makemigrations build python3 InvenTree/manage.py makemigrations order - python3 InvenTree/manage.py migrate - python3 InvenTree/manage.py migrate --run-syncdb + python3 InvenTree/manage.py makemigrations + cd InvenTree && python3 manage.py migrate + cd InvenTree && python3 manage.py migrate --run-syncdb python3 InvenTree/manage.py check - python3 InvenTree/manage.py collectstatic + cd InvenTree && python3 manage.py collectstatic # Install all required packages install: diff --git a/requirements.txt b/requirements.txt index a07aa8265f..cf45d83248 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,4 +14,5 @@ django-qr-code==1.0.0 # Generate QR codes flake8==3.3.0 # PEP checking coverage>=4.5.3 # Unit test coverage python-coveralls==2.9.1 # Coveralls linking (for Travis) -fuzzywuzzy>=0.17.0 # Fuzzy string matching \ No newline at end of file +fuzzywuzzy>=0.17.0 # Fuzzy string matching +python-Levenshtein>=0.12.0 # Required for fuzzywuzzy \ No newline at end of file