From 1df9aac9988f6ee439f55b1e8294257cc352bcb1 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 22 Jan 2021 11:42:24 +0000 Subject: [PATCH] added tests for company viewset --- companies/factories.py | 34 ++++++ companies/models.py | 2 +- companies/tests.py | 239 +++++++++++++++++++++++++++++++++++++++++ core/utils.py | 32 ++++++ 4 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 companies/factories.py create mode 100644 core/utils.py diff --git a/companies/factories.py b/companies/factories.py new file mode 100644 index 0000000..4fd8e80 --- /dev/null +++ b/companies/factories.py @@ -0,0 +1,34 @@ +import datetime +from django.utils import timezone +from factory import LazyAttribute, SubFactory +from factory.fuzzy import FuzzyText, FuzzyInteger, FuzzyDateTime, FuzzyDate, FuzzyDecimal, FuzzyChoice +from factory.django import DjangoModelFactory + +from companies.models import Company + +class CompanyFactory(DjangoModelFactory): + + cif = FuzzyText(prefix='CIF_', length=10) + company_name = FuzzyText(prefix='COMPANY_NAME_', length=10) + short_name = FuzzyText(prefix='SHORT_NAME_', length=10) + web_link = FuzzyText(prefix='http://WEB_LINK_', suffix='.test', length=10) + shop = FuzzyChoice(choices=(True, False)) + shop_link = FuzzyText(prefix='http://SHOP_LINK_', suffix='.test', length=10) + platform = FuzzyChoice(choices=[x[1] for x in Company.PLATFORMS]) + email = FuzzyText(prefix='EMAIL_', suffix='@test.com', length=10) + logo = None + city = None + address = FuzzyText(prefix='ADDRESS_', length=10) + geo = None + phone = '+34666555444' + mobile = '+34666555333' + other_phone = '+34666555222' + description = FuzzyText(prefix='DESCRIPTION_', length=250) + shop_rss_feed = FuzzyText(prefix='http://SHOP_RSS_FEED_', suffix='.test', length=10) + sale_terms = FuzzyText(prefix='SALES_TERMS', length=250) + shipping_cost = FuzzyDecimal(low=1.00) + # tags = models.ManyToMany(Tag, null=True) + sync = FuzzyChoice(choices=(True, False)) + + class Meta: + model = 'companies.Company' \ No newline at end of file diff --git a/companies/models.py b/companies/models.py index e193968..efb67c0 100644 --- a/companies/models.py +++ b/companies/models.py @@ -15,7 +15,7 @@ class Company(models.Model): (PRESTASHOP, 'Prestashop'), ) - cif = models.CharField('CIF', max_length=10, null=True, blank=True) + cif = models.CharField('CIF', max_length=15, null=True, blank=True) company_name = models.CharField('Razón Social Cooperativa', max_length=1000, null=True, blank=True) short_name = models.CharField('Apócope', max_length=100, null=True, blank=True) # autogenerar si blank web_link = models.URLField('Enlace a la web', null=True, blank=True) diff --git a/companies/tests.py b/companies/tests.py index 7ce503c..375a355 100644 --- a/companies/tests.py +++ b/companies/tests.py @@ -1,3 +1,242 @@ +import random +import string +import json + from django.test import TestCase +from rest_framework.test import APITestCase +from rest_framework import status + +from companies.factories import CompanyFactory +from companies.models import Company + +from core.utils import get_auth_token, create_active_user + + # Create your tests here. +class BuildingViewSetTest(APITestCase): + """Building viewset tests + """ + + def setUp(self): + """Tests setup + """ + self.endpoint = '/api/v1/companies/' + self.factory = CompanyFactory + self.model = Company + # create user + self.rand = ''.join(random.choices(string.ascii_uppercase, k = 5)) + self.password = ''.join(random.choices(string.ascii_uppercase, k = 10)) + self.email = f"{self.rand}@mail.com" + self.user = create_active_user(email=self.email, password=self.password) + + # user not authenticated + def test_not_logged_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_not_logged_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_not_logged_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_not_logged_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_logged_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_auth_token(self.client, self.email, self.password) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}") + + # 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_logged_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_auth_token(self.client, self.email, self.password) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}") + + # 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_logged_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_auth_token(self.client, self.email, self.password) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}") + + # 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_logged_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_auth_token(self.client, self.email, self.password) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}") + + # 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_logged_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_auth_token(self.client, self.email, self.password) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}") + + # 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_logged_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_auth_token(self.client, self.email, self.password) + self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token}") + + # 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()) diff --git a/core/utils.py b/core/utils.py new file mode 100644 index 0000000..c78133d --- /dev/null +++ b/core/utils.py @@ -0,0 +1,32 @@ +import logging + +from django.contrib.auth import get_user_model + + +User = get_user_model() + + +def get_auth_token(client, email, password): + credentials = { + 'email': email, + 'password': password, + } + response = client.post('/api/v1/token/', credentials, format='json') + if response.status_code == 200: + return response.data['access'] + else: + # logging.error(f"User {email} was refused a token: {response.content}") + return None + +def create_active_user(email, password): + user = User.objects.create_user(email=email, password=password) + user.is_active = True + user.save() + return user + +def create_admin_user(email, password): + user = User.objects.create_user(email=email, password=password) + user.is_staff = True + user.is_active = True + user.save() + return user