diff --git a/products/factories.py b/products/factories.py new file mode 100644 index 0000000..e5873fd --- /dev/null +++ b/products/factories.py @@ -0,0 +1,36 @@ +import datetime +from django.utils import timezone +from factory import SubFactory +from factory.fuzzy import FuzzyText, FuzzyInteger, FuzzyDateTime, FuzzyDate, FuzzyDecimal, FuzzyChoice, FuzzyDateTime +from factory.django import DjangoModelFactory + +from companies.factories import CompanyFactory + +from products.models import Product + + + +class ProductFactory(DjangoModelFactory): + + company = SubFactory(CompanyFactory) + sku = FuzzyText(prefix='SKU_', length=10) + name = FuzzyText(prefix='NAME_', length=10) + description = FuzzyText(prefix='DECRIPTION', length=100) + image = None + url = FuzzyText(prefix='http://WEB_LINK_', suffix='.test', length=10) + price = FuzzyDecimal(low=1.00) + shipping_cost = FuzzyDecimal(low=1.00) + shipping_terms = FuzzyText(prefix='SHIPPING_TERMS', length=100) + source = FuzzyChoice(choices=[x[1] for x in Product.SOURCES]) + sourcing_date = FuzzyDateTime(start_dt=timezone.now()) + update_date = FuzzyDateTime(start_dt=timezone.now()) + discount = FuzzyDecimal(low=0.00, high=100.00) + stock = FuzzyInteger(low=0) + # tags = models.ManyToMany(Tag, null=True, blank=True ) + # category = models.ForeignKey(Tag, null=true) # main tag category + # attributes = models.ManyToMany(Tag, null=True, blank=True ) + identifiers = FuzzyText(prefix='IDENTIFIERS_', length=100) + + class Meta: + model = Product + diff --git a/products/tests.py b/products/tests.py index 7ce503c..7733e18 100644 --- a/products/tests.py +++ b/products/tests.py @@ -1,3 +1,239 @@ -from django.test import TestCase +import random +import string +import json + +from rest_framework.test import APITestCase +from rest_framework import status + +from products.factories import ProductFactory +from products.models import Product + +from core.factories import CustomUserFactory +from core.utils import get_tokens_for_user + # Create your tests here. +class ProductViewSetTest(APITestCase): + """ProductViewSet tests + """ + + def setUp(self): + """Tests setup + """ + self.endpoint = '/api/v1/products/' + self.factory = ProductFactory + self.model = Product + # create user + self.password = ''.join(random.choices(string.ascii_uppercase, k = 10)) + self.user = CustomUserFactory(password=self.password) + + # user not authenticated + def test_anon_user_cannot_create_instance(self): + """Not logged-in user cannot create new instance + """ + instances = [self.factory() for n in range(random.randint(1,5))] + + # Query endpoint + response = self.client.post(self.endpoint, data={}) + # Assert access is forbidden + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + def test_anon_user_cannot_modify_existing_instance(self): + """Not logged-in user cannot modify existing instance + """ + # Create instance + instance = self.factory() + + # Query endpoint + url = self.endpoint + f'{instance.pk}/' + response = self.client.put(url, {}, format='json') + + # Assert forbidden code + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + def test_anon_user_cannot_delete_existing_instance(self): + """Not logged-in user cannot delete existing instance + """ + # Create instances + instance = self.factory() + + # Query endpoint + url = self.endpoint + f'{instance.pk}/' + response = self.client.delete(url) + + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + # Assert instance still exists on db + self.assertTrue(self.model.objects.get(id=instance.pk)) + + def test_anon_user_can_list_instance(self): + """Not logged-in user can list instance + """ + # Request list + response = self.client.get(self.endpoint) + + # Assert access is forbidden + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # authenticated user + def test_auth_user_can_list_instance(self): + """Regular logged-in user can list instance + """ + # Create instances + instances = [self.factory() for n in range(random.randint(1,5))] + + # Authenticate user + token = get_tokens_for_user(self.user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + # Request list + response = self.client.get(self.endpoint) + + # Assert access is allowed + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Assert all instances are returned + self.assertEqual(len(instances), len(response.data)) + + def test_auth_user_can_create_instance(self): + """Regular logged-in user can create new instance + """ + # Define request data + data = { + 'cif': 'qwerewq', + 'company_name': 'qwerewq', + 'short_name': 'qwerewq', + 'web_link': 'http://qwerewq.com', + 'shop': True, + 'shop_link': 'http://qwerewq.com', + 'platform': 'PRESTASHOP', + 'email': 'test@email.com', + 'logo': None, + 'city': None, + 'address': 'qwer qewr 5', + 'geo': None, + 'phone': '1234', + 'mobile': '4321', + 'other_phone': '41423', + 'description': 'dfgfdgdfg', + 'shop_rss_feed': 'http://qwerewq.com', + 'sale_terms': 'tewrnmfew f ewfrfew ewewew f', + 'shipping_cost': '12.25', + 'sync': False + } + + # Authenticate user + token = get_tokens_for_user(self.user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + # Query endpoint + response = self.client.post(self.endpoint, data=data, format='json') + + # Assert endpoint returns created status + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + # Assert instance exists on db + self.assertTrue(self.model.objects.get(id=response.data['id'])) + + def test_auth_user_can_modify_own_instance(self): + """Regular logged-in user can modify existing instance + """ + # Create instances + instance = self.factory() + # make our user the creator + instance.creator = self.user + instance.save() + + # Define request data + data = { + 'cif': 'qwerewq', + 'company_name': 'qwerewq', + 'short_name': 'qwerewq', + 'web_link': 'http://qwerewq.com', + 'shop': True, + 'shop_link': 'http://qwerewq.com', + 'platform': 'PRESTASHOP', + 'email': 'test@email.com', + 'logo': None, + 'city': None, + 'address': 'qwer qewr 5', + 'geo': None, + 'phone': '1234', + 'mobile': '4321', + 'other_phone': '41423', + 'description': 'dfgfdgdfg', + 'shop_rss_feed': 'http://qwerewq.com', + 'sale_terms': 'tewrnmfew f ewfrfew ewewew f', + 'shipping_cost': '12.25', + 'sync': False + } + + # Authenticate user + token = get_tokens_for_user(self.user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + # Query endpoint + url = self.endpoint + f'{instance.pk}/' + response = self.client.put(url, data, format='json') + + # Assert endpoint returns OK code + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Assert instance has been modified + for key in data: + self.assertEqual(data[key], response.data[key]) + + def test_auth_user_cannot_modify_other_users_instance(self): + """Regular logged-in user cannot modify other user's instance + """ + # Create instances + instance = self.factory() + + # Authenticate user + token = get_tokens_for_user(self.user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + # Query endpoint + url = self.endpoint + f'{instance.pk}/' + response = self.client.put(url, data={}, format='json') + + # Assert endpoint returns OK code + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_auth_user_cannot_delete_other_users_instance(self): + """Regular logged-in user cannot delete other user's instance + """ + # Create instances + instance = self.factory() + + # Authenticate user + token = get_tokens_for_user(self.user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + # Query endpoint + url = self.endpoint + f'{instance.pk}/' + response = self.client.delete(url, format='json') + + # Assert endpoint returns OK code + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_auth_user_can_delete_own_instance(self): + """Regular logged-in user can delete existing instance + """ + # Create instances + instance = self.factory() + # make our user the creator + instance.creator = self.user + instance.save() + + # Authenticate user + token = get_tokens_for_user(self.user) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}") + + # Query endpoint + url = self.endpoint + f'{instance.pk}/' + response = self.client.delete(url) + + # assert 204 no content + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + # Assert instance doesn't exists anymore on db + self.assertFalse(self.model.objects.filter(id=instance.pk).exists())