Merge branch 'development' into diego
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
from core.views import CustomUserViewSet
|
from core.views import CustomUserViewSet
|
||||||
from companies.views import CompanyViewSet, MyCompanyViewSet, AdminCompanyViewSet
|
from companies.views import CompanyViewSet, AdminCompanyViewSet
|
||||||
from products.views import ProductViewSet, MyProductsViewSet, AdminProductsViewSet
|
from products.views import ProductViewSet, MyProductsViewSet, AdminProductsViewSet
|
||||||
from history.views import HistorySyncViewSet
|
from history.views import HistorySyncViewSet
|
||||||
from stats.views import StatsLogViewSet
|
from stats.views import StatsLogViewSet
|
||||||
@@ -13,7 +13,6 @@ router = routers.DefaultRouter()
|
|||||||
|
|
||||||
router.register('users', CustomUserViewSet, basename='users')
|
router.register('users', CustomUserViewSet, basename='users')
|
||||||
router.register('companies', CompanyViewSet, basename='company')
|
router.register('companies', CompanyViewSet, basename='company')
|
||||||
router.register('my_company', MyCompanyViewSet, basename='my-company')
|
|
||||||
router.register('admin_companies', AdminCompanyViewSet, basename='admin-companies')
|
router.register('admin_companies', AdminCompanyViewSet, basename='admin-companies')
|
||||||
router.register('products', ProductViewSet, basename='product')
|
router.register('products', ProductViewSet, basename='product')
|
||||||
router.register('my_products', MyProductsViewSet, basename='my-products')
|
router.register('my_products', MyProductsViewSet, basename='my-products')
|
||||||
|
|||||||
@@ -171,3 +171,6 @@ MAP_WIDGETS = {
|
|||||||
),
|
),
|
||||||
"GOOGLE_MAP_API_KEY": os.getenv('GOOGLE_MAP_API_KEY')
|
"GOOGLE_MAP_API_KEY": os.getenv('GOOGLE_MAP_API_KEY')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ACTIVATION_REDIRECT URL
|
||||||
|
ACTIVATION_REDIRECT = os.getenv('ACTIVATION_REDIRECT')
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ urlpatterns = [
|
|||||||
path('api/v1/search_products/', product_views.product_search, name='product-search'),
|
path('api/v1/search_products/', product_views.product_search, name='product-search'),
|
||||||
path('api/v1/create_company_user/', core_views.create_company_user, name='create-company-user'),
|
path('api/v1/create_company_user/', core_views.create_company_user, name='create-company-user'),
|
||||||
path('api/v1/my_user/', core_views.my_user, name='my-user'),
|
path('api/v1/my_user/', core_views.my_user, name='my-user'),
|
||||||
|
path('api/v1/my_company/', company_views.my_company, name='my-company'),
|
||||||
path('api/v1/companies/sample/', company_views.random_company_sample , name='company-sample'),
|
path('api/v1/companies/sample/', company_views.random_company_sample , name='company-sample'),
|
||||||
path('api/v1/purchase_email/', product_views.purchase_email, name='purchase-email'),
|
path('api/v1/purchase_email/', product_views.purchase_email, name='purchase-email'),
|
||||||
path('api/v1/stats/me/', stat_views.track_user, name='user-tracker'),
|
path('api/v1/stats/me/', stat_views.track_user, name='user-tracker'),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.gis.db.models import PointField
|
from django.contrib.gis.db.models import PointField
|
||||||
|
|
||||||
from django_admin_listfilter_dropdown.filters import DropdownFilter, RelatedDropdownFilter
|
from django_admin_listfilter_dropdown.filters import DropdownFilter
|
||||||
from mapwidgets.widgets import GooglePointFieldWidget
|
from mapwidgets.widgets import GooglePointFieldWidget
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
@@ -10,8 +10,8 @@ from . import models
|
|||||||
|
|
||||||
class CompanyAdmin(admin.ModelAdmin):
|
class CompanyAdmin(admin.ModelAdmin):
|
||||||
list_display = ('short_name', 'city', 'email', 'shop', 'platform', 'sync', 'is_validated', 'is_active', 'link')
|
list_display = ('short_name', 'city', 'email', 'shop', 'platform', 'sync', 'is_validated', 'is_active', 'link')
|
||||||
list_filter = ('platform', 'sync', 'is_validated', 'is_active', 'city')
|
list_filter = ('platform', 'sync', 'is_validated', 'is_active', ('city', DropdownFilter))
|
||||||
search_fields = ('short_name', 'company_name', 'email', 'web_link', ('city', RelatedDropdownFilter))
|
search_fields = ('short_name', 'company_name', 'email', 'web_link', 'city')
|
||||||
|
|
||||||
formfield_overrides = {
|
formfield_overrides = {
|
||||||
PointField: {"widget": GooglePointFieldWidget}
|
PointField: {"widget": GooglePointFieldWidget}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ class CompanyViewSetTest(APITestCase):
|
|||||||
'logo': None,
|
'logo': None,
|
||||||
'city': None,
|
'city': None,
|
||||||
'address': 'qwer qewr 5',
|
'address': 'qwer qewr 5',
|
||||||
'geo': None,
|
'geo': {'longitude': 1.0, 'latitude': 1.0},
|
||||||
'phone': '1234',
|
'phone': '1234',
|
||||||
'mobile': '4321',
|
'mobile': '4321',
|
||||||
'other_phone': '41423',
|
'other_phone': '41423',
|
||||||
@@ -312,12 +312,11 @@ class MyCompanyViewTest(APITestCase):
|
|||||||
self.user.set_password(self.password)
|
self.user.set_password(self.password)
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
self.model.objects.all().delete()
|
|
||||||
|
|
||||||
def test_auth_user_gets_data(self):
|
def test_auth_user_gets_data(self):
|
||||||
# create instance
|
# create instance
|
||||||
user_instances = [self.factory(creator=self.user) for i in range(5)]
|
company = CompanyFactory()
|
||||||
|
self.user.company = company
|
||||||
|
self.user.save()
|
||||||
|
|
||||||
# Authenticate
|
# Authenticate
|
||||||
token = get_tokens_for_user(self.user)
|
token = get_tokens_for_user(self.user)
|
||||||
@@ -325,32 +324,10 @@ class MyCompanyViewTest(APITestCase):
|
|||||||
|
|
||||||
# Query endpoint
|
# Query endpoint
|
||||||
response = self.client.get(self.endpoint)
|
response = self.client.get(self.endpoint)
|
||||||
payload = response.json()
|
|
||||||
|
|
||||||
# Assert forbidden code
|
# Assert forbidden code
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
self.assertEquals(len(user_instances), len(payload))
|
|
||||||
|
|
||||||
def test_auth_user_can_paginate_instances(self):
|
|
||||||
"""authenticated user can paginate instances
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Authenticate
|
|
||||||
token = get_tokens_for_user(self.user)
|
|
||||||
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
|
||||||
|
|
||||||
# create instances
|
|
||||||
instances = [self.factory(creator=self.user) for n in range(12)]
|
|
||||||
|
|
||||||
# Request list
|
|
||||||
url = f"{self.endpoint}?limit=5&offset=10"
|
|
||||||
response = self.client.get(url)
|
|
||||||
|
|
||||||
# Assert access is allowed
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
||||||
# assert only 2 instances in response
|
|
||||||
payload = response.json()
|
payload = response.json()
|
||||||
self.assertEquals(2, len(payload['results']))
|
self.assertEquals(payload['company']['id'], company.id)
|
||||||
|
|
||||||
def test_anon_user_cannot_access(self):
|
def test_anon_user_cannot_access(self):
|
||||||
# send in request
|
# send in request
|
||||||
|
|||||||
@@ -155,17 +155,27 @@ class CompanyViewSet(viewsets.ModelViewSet):
|
|||||||
return Response(message)
|
return Response(message)
|
||||||
|
|
||||||
|
|
||||||
|
@api_view(['GET'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
def my_company(request):
|
||||||
|
if request.user.company:
|
||||||
|
serializer = CompanySerializer(request.user.company)
|
||||||
|
return Response({'company': serializer.data})
|
||||||
|
else:
|
||||||
|
return Response(status=status.HTTP_406_NOT_ACCEPTABLE)
|
||||||
|
|
||||||
|
'''
|
||||||
class MyCompanyViewSet(viewsets.ModelViewSet):
|
class MyCompanyViewSet(viewsets.ModelViewSet):
|
||||||
model = Company
|
model = Company
|
||||||
serializer_class = CompanySerializer
|
serializer_class = CompanySerializer
|
||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.model.objects.filter(creator=self.request.user)
|
return self.model.objects.filter(company=self.request.user.company)
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(creator=self.request.user)
|
serializer.save(creator=self.request.user)
|
||||||
|
'''
|
||||||
|
|
||||||
class AdminCompanyViewSet(viewsets.ModelViewSet):
|
class AdminCompanyViewSet(viewsets.ModelViewSet):
|
||||||
""" Allows user with role 'SITE_ADMIN' to access all company instances
|
""" Allows user with role 'SITE_ADMIN' to access all company instances
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ class UserManager(BaseUserManager):
|
|||||||
|
|
||||||
def create_user(self, email, password=None, **extra_fields):
|
def create_user(self, email, password=None, **extra_fields):
|
||||||
extra_fields.setdefault('is_superuser', False)
|
extra_fields.setdefault('is_superuser', False)
|
||||||
|
extra_fields.setdefault('is_staff', False)
|
||||||
|
extra_fields.setdefault('is_active', False)
|
||||||
return self._create_user(email, password, **extra_fields)
|
return self._create_user(email, password, **extra_fields)
|
||||||
|
|
||||||
def create_superuser(self, email, password, **extra_fields):
|
def create_superuser(self, email, password, **extra_fields):
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class CustomUserWriteSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.CustomUser
|
model = models.CustomUser
|
||||||
fields = ('email', 'full_name', 'role', 'password', 'provider')
|
fields = ('email', 'full_name', 'role', 'password', 'provider', 'notify')
|
||||||
|
|
||||||
|
|
||||||
class CreatorSerializer(serializers.ModelSerializer):
|
class CreatorSerializer(serializers.ModelSerializer):
|
||||||
|
|||||||
198
core/tests.py
198
core/tests.py
@@ -9,6 +9,7 @@ from django.test import TestCase
|
|||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.utils.http import urlsafe_base64_encode
|
from django.utils.http import urlsafe_base64_encode
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
@@ -41,7 +42,7 @@ class CustomUserViewSetTest(APITestCase):
|
|||||||
self.user = self.factory(email=self.reg_email, password=self.password, is_active=True)
|
self.user = self.factory(email=self.reg_email, password=self.password, is_active=True)
|
||||||
|
|
||||||
# anon user
|
# anon user
|
||||||
def test_anon_user_can_create_active_instance(self):
|
def test_anon_user_can_create_inactive_instance(self):
|
||||||
"""Not logged-in user can create new instance of User but it's inactive
|
"""Not logged-in user can create new instance of User but it's inactive
|
||||||
"""
|
"""
|
||||||
data = {
|
data = {
|
||||||
@@ -57,7 +58,7 @@ class CustomUserViewSetTest(APITestCase):
|
|||||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||||
# assert instance is inactive
|
# assert instance is inactive
|
||||||
info = json.loads(response.content)
|
info = json.loads(response.content)
|
||||||
self.assertTrue(info['is_active'])
|
self.assertFalse(info['is_active'])
|
||||||
# Assert instance exists on db
|
# Assert instance exists on db
|
||||||
self.assertTrue(self.model.objects.get(email=info['email']))
|
self.assertTrue(self.model.objects.get(email=info['email']))
|
||||||
# assert verification email
|
# assert verification email
|
||||||
@@ -161,6 +162,27 @@ class CustomUserViewSetTest(APITestCase):
|
|||||||
# Assert access is forbidden
|
# Assert access is forbidden
|
||||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||||
|
|
||||||
|
def test_auth_user_can_modify_own_instance(self):
|
||||||
|
"""Regular user can modify own instance
|
||||||
|
"""
|
||||||
|
# Create instance
|
||||||
|
data = {
|
||||||
|
"email": "new_email@mail.com",
|
||||||
|
"full_name": "New Full Name",
|
||||||
|
'provider': 'PROVIDER',
|
||||||
|
'notify': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Authenticate
|
||||||
|
token = get_tokens_for_user(self.user)
|
||||||
|
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
||||||
|
|
||||||
|
# Query endpoint
|
||||||
|
url = f'{self.endpoint}{self.user.pk}/'
|
||||||
|
response = self.client.put(url, data=data, format='json')
|
||||||
|
# Assert forbidden code
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
|
||||||
# admin user
|
# admin user
|
||||||
def test_admin_user_can_create_instance(self):
|
def test_admin_user_can_create_instance(self):
|
||||||
"""Admin user can create new instance
|
"""Admin user can create new instance
|
||||||
@@ -332,99 +354,6 @@ class ChangeUserPasswordViewTest(APITestCase):
|
|||||||
self.assertEqual(stored_password_hash, base64.b64encode(new_password_hash).decode())
|
self.assertEqual(stored_password_hash, base64.b64encode(new_password_hash).decode())
|
||||||
|
|
||||||
|
|
||||||
class UpdateUserViewTest(APITestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
"""Tests setup
|
|
||||||
"""
|
|
||||||
self.endpoint = '/api/v1/users/'
|
|
||||||
self.factory = factories.CustomUserFactory
|
|
||||||
self.model = models.CustomUser
|
|
||||||
# create regular user
|
|
||||||
self.reg_email = f"user@mail.com"
|
|
||||||
self.password = ''.join(random.choices(string.ascii_uppercase, k = 10))
|
|
||||||
self.user = self.factory(email=self.reg_email, is_active=True)
|
|
||||||
self.user.set_password(self.password)
|
|
||||||
self.user.save()
|
|
||||||
# create admin user
|
|
||||||
self.admin_email = f"admin_user@mail.com"
|
|
||||||
self.admin_user = self.factory(email=self.admin_email, is_staff=True, is_active=True)
|
|
||||||
self.admin_user.set_password(self.password)
|
|
||||||
self.admin_user.save()
|
|
||||||
|
|
||||||
def test_auth_user_can_modify_own_instance(self):
|
|
||||||
"""Regular user can modify own instance
|
|
||||||
"""
|
|
||||||
# Create instance
|
|
||||||
data = {
|
|
||||||
"email": "new_email@mail.com",
|
|
||||||
"full_name": "New Full Name",
|
|
||||||
'provider': 'PROVIDER',
|
|
||||||
'notify': True,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Authenticate
|
|
||||||
token = get_tokens_for_user(self.user)
|
|
||||||
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
|
||||||
|
|
||||||
# Query endpoint
|
|
||||||
url = f'{self.endpoint}{self.user.pk}/'
|
|
||||||
response = self.client.put(url, data=data, format='json')
|
|
||||||
# Assert forbidden code
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
||||||
|
|
||||||
def test_auth_user_cannot_modify_random_instance(self):
|
|
||||||
"""Regular user cannot modify randnom instance
|
|
||||||
"""
|
|
||||||
# Create instance
|
|
||||||
instance = self.factory()
|
|
||||||
|
|
||||||
# Authenticate
|
|
||||||
token = get_tokens_for_user(self.user)
|
|
||||||
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
|
||||||
|
|
||||||
# Query endpoint
|
|
||||||
url = f'{self.endpoint}{instance.pk}/'
|
|
||||||
response = self.client.put(url, data={}, format='json')
|
|
||||||
# Assert forbidden code
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
|
||||||
|
|
||||||
def test_anon_user_cannot_modify_random_instance(self):
|
|
||||||
"""anon user cannot modify instance
|
|
||||||
"""
|
|
||||||
# Create instance
|
|
||||||
instance = self.factory()
|
|
||||||
|
|
||||||
# Query endpoint
|
|
||||||
url = f'{self.endpoint}{instance.pk}/'
|
|
||||||
response = self.client.put(url, data={}, format='json')
|
|
||||||
# Assert forbidden code
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
|
||||||
|
|
||||||
def test_admin_user_can_modify_random_instance(self):
|
|
||||||
"""Regular user cannot modify randnom instance
|
|
||||||
"""
|
|
||||||
# Create instance
|
|
||||||
instance = self.factory()
|
|
||||||
|
|
||||||
# Authenticate
|
|
||||||
token = get_tokens_for_user(self.admin_user)
|
|
||||||
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"email": "new_email@mail.com",
|
|
||||||
"full_name": "New Full Name",
|
|
||||||
'provider': 'PROVIDER',
|
|
||||||
'notify': True,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Query endpoint
|
|
||||||
url = f'{self.endpoint}{instance.pk}/'
|
|
||||||
response = self.client.put(url, data=data, format='json')
|
|
||||||
# Assert forbidden code
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
|
||||||
|
|
||||||
|
|
||||||
class LoadCoopManagerTestCase(APITestCase):
|
class LoadCoopManagerTestCase(APITestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -564,6 +493,21 @@ class ActivateUserTest(APITestCase):
|
|||||||
|
|
||||||
response = self.client.get(url)
|
response = self.client.get(url)
|
||||||
|
|
||||||
|
# assertions
|
||||||
|
self.assertEquals(response.status_code, 302)
|
||||||
|
self.assertEquals(response.url, settings.ACTIVATION_REDIRECT)
|
||||||
|
|
||||||
|
def test_correct_activation_no_redirect(self):
|
||||||
|
# set ACTIVATION_REDIRECT to ''
|
||||||
|
settings.ACTIVATION_REDIRECT = ''
|
||||||
|
# create values
|
||||||
|
uid = urlsafe_base64_encode(force_bytes(self.user.pk))
|
||||||
|
token = account_activation_token.make_token(self.user)
|
||||||
|
|
||||||
|
url = f'/activate/{uid}/{token}/'
|
||||||
|
|
||||||
|
response = self.client.get(url)
|
||||||
|
|
||||||
# assertions
|
# assertions
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
self.assertTrue(self.user.email in str(response.content))
|
self.assertTrue(self.user.email in str(response.content))
|
||||||
@@ -580,3 +524,67 @@ class ActivateUserTest(APITestCase):
|
|||||||
# assertions
|
# assertions
|
||||||
self.assertEquals(response.status_code, 406)
|
self.assertEquals(response.status_code, 406)
|
||||||
self.assertTrue('error' in response.json())
|
self.assertTrue('error' in response.json())
|
||||||
|
|
||||||
|
|
||||||
|
class CreateCompanyUserTest(APITestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.endpoint = '/api/v1/create_company_user/'
|
||||||
|
self.factory = factories.CustomUserFactory
|
||||||
|
self.model = models.CustomUser
|
||||||
|
# create user
|
||||||
|
self.email = "user@mail.com"
|
||||||
|
self.password = ''.join(random.choices(string.ascii_uppercase, k = 10))
|
||||||
|
self.user = self.factory(email=self.email, is_active=False)
|
||||||
|
self.user.set_password(self.password)
|
||||||
|
self.user.save()
|
||||||
|
|
||||||
|
def test_succesful_creation(self):
|
||||||
|
data = {
|
||||||
|
'user': {
|
||||||
|
'email': 'test@email.com',
|
||||||
|
'full_name': 'TEST NAME',
|
||||||
|
'password': 'VENTILADORES1234499.89',
|
||||||
|
},
|
||||||
|
'company': {
|
||||||
|
'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': {'longitude': 1.0, 'latitude': 1.0},
|
||||||
|
'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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = self.client.post(self.endpoint, data=data, format='json')
|
||||||
|
|
||||||
|
self.assertEquals(response.status_code, 201)
|
||||||
|
self.assertEquals(len(mail.outbox), 1)
|
||||||
|
# user exists and it's inactice
|
||||||
|
self.assertTrue(self.model.objects.get(email='test@email.com'))
|
||||||
|
self.assertFalse(self.model.objects.get(email='test@email.com').is_active)
|
||||||
|
self.assertTrue(Company.objects.get(cif='qwerewq'))
|
||||||
|
# assert verification email
|
||||||
|
self.assertTrue(len(mail.outbox) == 1)
|
||||||
|
|
||||||
|
def test_creation_error(self):
|
||||||
|
|
||||||
|
response = self.client.post(self.endpoint, data={}, format='json')
|
||||||
|
|
||||||
|
self.assertEquals(response.status_code, 406)
|
||||||
|
self.assertEquals(len(mail.outbox), 0)
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ from django.utils.http import urlsafe_base64_decode
|
|||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
from django.contrib.gis.geos import Point
|
from django.contrib.gis.geos import Point
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
@@ -20,6 +22,7 @@ from rest_framework.generics import UpdateAPIView
|
|||||||
from rest_framework.decorators import api_view, permission_classes
|
from rest_framework.decorators import api_view, permission_classes
|
||||||
|
|
||||||
from companies.models import Company
|
from companies.models import Company
|
||||||
|
from companies.serializers import CompanySerializer
|
||||||
from geo.models import City
|
from geo.models import City
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
@@ -43,9 +46,9 @@ logging.basicConfig(
|
|||||||
|
|
||||||
class CustomUserViewSet(viewsets.ModelViewSet):
|
class CustomUserViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
model = models.CustomUser
|
model = User
|
||||||
model_name = 'custom_user'
|
model_name = 'custom_user'
|
||||||
queryset = models.CustomUser.objects.all()
|
queryset = User.objects.all()
|
||||||
permission_classes = [CustomUserPermissions,]
|
permission_classes = [CustomUserPermissions,]
|
||||||
read_serializer_class = core_serializers.CustomUserReadSerializer
|
read_serializer_class = core_serializers.CustomUserReadSerializer
|
||||||
write_serializer_class = core_serializers.CustomUserWriteSerializer
|
write_serializer_class = core_serializers.CustomUserWriteSerializer
|
||||||
@@ -76,7 +79,7 @@ class CustomUserViewSet(viewsets.ModelViewSet):
|
|||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
# save model instance data
|
# save model instance data
|
||||||
password = serializer.validated_data.pop('password')
|
password = serializer.validated_data.pop('password')
|
||||||
instance = self.model(**serializer.validated_data)
|
instance = self.model.objects.create_user(**serializer.validated_data)
|
||||||
instance.set_password(password)
|
instance.set_password(password)
|
||||||
instance.save()
|
instance.save()
|
||||||
# send verification email
|
# send verification email
|
||||||
@@ -100,63 +103,47 @@ class ChangeUserPasswordView(UpdateAPIView):
|
|||||||
serializer_class = core_serializers.ChangePasswordSerializer
|
serializer_class = core_serializers.ChangePasswordSerializer
|
||||||
|
|
||||||
|
|
||||||
class UpdateUserView(UpdateAPIView):
|
|
||||||
|
|
||||||
model = models.CustomUser
|
|
||||||
queryset = model.objects.all()
|
|
||||||
permission_classes = (YourOwnUserPermissions,)
|
|
||||||
serializer_class = core_serializers.UpdateUserSerializer
|
|
||||||
|
|
||||||
|
|
||||||
@api_view(['POST',])
|
@api_view(['POST',])
|
||||||
@permission_classes([CustomUserPermissions,])
|
@permission_classes([CustomUserPermissions,])
|
||||||
def create_company_user(request):
|
def create_company_user(request):
|
||||||
"""
|
"""
|
||||||
Create non-validated company and manager user associated
|
Create non-validated company and associated managing user
|
||||||
"""
|
"""
|
||||||
user_data = {
|
if 'user' not in request.data:
|
||||||
'full_name': request.data['user']['full_name'],
|
return Response({"error": "Missing parameter: user"}, status=406)
|
||||||
'email': request.data['user']['email'],
|
if 'company' not in request.data:
|
||||||
'password': request.data['user']['password']
|
return Response({"error": "Missing parameter: company"}, status=406)
|
||||||
}
|
|
||||||
company_data = {
|
|
||||||
'cif': request.data['company']['cif'],
|
|
||||||
'company_name': request.data['company']['company_name'],
|
|
||||||
'short_name': request.data['company']['short_name'],
|
|
||||||
'web_link': request.data['company']['web_link'],
|
|
||||||
'shop': request.data['company']['shop'],
|
|
||||||
'city': request.data['company']['city'],
|
|
||||||
'geo': request.data['company']['geo'],
|
|
||||||
'address': request.data['company']['address']
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
user = models.CustomUser.objects.create(email=user_data['email'], full_name=user_data['full_name'])
|
|
||||||
except IntegrityError as e:
|
|
||||||
return Response({"errors": {"details": str(e)}}, status=status.HTTP_409_CONFLICT)
|
|
||||||
|
|
||||||
try:
|
# create company
|
||||||
city = company_data.pop('city')
|
company_data = request.data['company']
|
||||||
#city = City.objects.get(name=city)
|
company_serializer = CompanySerializer(
|
||||||
|
data=company_data,
|
||||||
|
)
|
||||||
|
if company_serializer.is_valid():
|
||||||
|
# save model instance data
|
||||||
|
new_company = Company.objects.create(**company_serializer.validated_data)
|
||||||
|
else:
|
||||||
|
return Response({"error": company_serializer.errors}, status=406)
|
||||||
|
|
||||||
geo = company_data.pop('geo')
|
# create user
|
||||||
geo = Point(geo['latitude'],geo['longitude'])
|
user_data = request.data['user']
|
||||||
|
user_data['role'] = 'COOP_MANAGER'
|
||||||
|
user_data['company'] = new_company.id
|
||||||
|
user_serializer = core_serializers.CustomUserWriteSerializer(
|
||||||
|
data=user_data,
|
||||||
|
)
|
||||||
|
if user_serializer.is_valid():
|
||||||
|
# save model instance data
|
||||||
|
password = user_serializer.validated_data.pop('password')
|
||||||
|
new_user = User.objects.create_user(**user_serializer.validated_data)
|
||||||
|
new_user.set_password(password)
|
||||||
|
new_user.save()
|
||||||
|
# send verification email
|
||||||
|
utils.send_verification_email(request, new_user)
|
||||||
|
else:
|
||||||
|
return Response({"error": user_serializer.errors}, status=406)
|
||||||
|
|
||||||
company = Company.objects.create(**company_data, city=city, geo=geo)
|
return Response(status=status.HTTP_201_CREATED)
|
||||||
except Exception as e:
|
|
||||||
user.delete()
|
|
||||||
return Response({"errors": {"details": str(e)}}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
||||||
|
|
||||||
user.set_password(user_data['password'])
|
|
||||||
user.company = company
|
|
||||||
user.role = 'COOP_MANAGER'
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
company.creator = user
|
|
||||||
company.save()
|
|
||||||
|
|
||||||
serializer = core_serializers.CustomUserSerializer(user)
|
|
||||||
|
|
||||||
return Response(data=serializer.data,status=status.HTTP_201_CREATED)
|
|
||||||
|
|
||||||
|
|
||||||
@api_view(['GET',])
|
@api_view(['GET',])
|
||||||
@@ -205,6 +192,8 @@ def activate_user(request, uidb64, token):
|
|||||||
# activate user
|
# activate user
|
||||||
user.is_active = True
|
user.is_active = True
|
||||||
user.save()
|
user.save()
|
||||||
|
if settings.ACTIVATION_REDIRECT:
|
||||||
|
return redirect(settings.ACTIVATION_REDIRECT)
|
||||||
return Response(f"Tu cuenta de usuario {user.email} ha sido activada")
|
return Response(f"Tu cuenta de usuario {user.email} ha sido activada")
|
||||||
else:
|
else:
|
||||||
return Response({"error": f"Tu token de verificacion no coincide con ningún usuario registrado"}, status=status.HTTP_406_NOT_ACCEPTABLE)
|
return Response({"error": f"Tu token de verificacion no coincide con ningún usuario registrado"}, status=status.HTTP_406_NOT_ACCEPTABLE)
|
||||||
|
|||||||
@@ -15,3 +15,5 @@ WC_KEY = ''
|
|||||||
WC_SECRET = ''
|
WC_SECRET = ''
|
||||||
# GOOGLE MAPS
|
# GOOGLE MAPS
|
||||||
GOOGLE_MAP_API_KEY = ''
|
GOOGLE_MAP_API_KEY = ''
|
||||||
|
# USER ACTIVATION REDIRECTION
|
||||||
|
ACTIVATION_REDIRECT = ''
|
||||||
@@ -952,9 +952,13 @@ class MyProductsViewTest(APITestCase):
|
|||||||
|
|
||||||
def test_auth_user_gets_data(self):
|
def test_auth_user_gets_data(self):
|
||||||
# create instance
|
# create instance
|
||||||
|
company = CompanyFactory()
|
||||||
|
self.user.company = company
|
||||||
|
self.user.save()
|
||||||
|
|
||||||
user_instances = [
|
user_instances = [
|
||||||
self.factory(creator=self.user),
|
self.factory(company=company),
|
||||||
self.factory(creator=self.user),
|
self.factory(company=company),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Authenticate
|
# Authenticate
|
||||||
@@ -976,7 +980,11 @@ class MyProductsViewTest(APITestCase):
|
|||||||
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
||||||
|
|
||||||
# create instances
|
# create instances
|
||||||
instances = [self.factory(creator=self.user) for n in range(12)]
|
company = CompanyFactory()
|
||||||
|
self.user.company = company
|
||||||
|
self.user.save()
|
||||||
|
|
||||||
|
instances = [self.factory(company=company) for n in range(12)]
|
||||||
|
|
||||||
# Request list
|
# Request list
|
||||||
url = f"{self.endpoint}?limit=5&offset=10"
|
url = f"{self.endpoint}?limit=5&offset=10"
|
||||||
@@ -996,6 +1004,18 @@ class MyProductsViewTest(APITestCase):
|
|||||||
# check response
|
# check response
|
||||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||||
|
|
||||||
|
def test_auth_user_without_company(self):
|
||||||
|
# Authenticate
|
||||||
|
token = get_tokens_for_user(self.user)
|
||||||
|
self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {token['access']}")
|
||||||
|
|
||||||
|
# Query endpoint
|
||||||
|
response = self.client.get(self.endpoint)
|
||||||
|
payload = response.json()
|
||||||
|
# Assert forbidden code
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEquals([], payload)
|
||||||
|
|
||||||
|
|
||||||
class AdminProductViewSetTest(APITestCase):
|
class AdminProductViewSetTest(APITestCase):
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from django.db.models import Q
|
|||||||
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector, TrigramSimilarity
|
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector, TrigramSimilarity
|
||||||
from django.db.models import Max, Min
|
from django.db.models import Max, Min
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
@@ -203,7 +204,7 @@ def product_loader(csv_reader, user, company=None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# create historysync instance
|
# create historysync instance
|
||||||
history = HistorySync.objects.create(company=company, sync_date=datetime.datetime.now())
|
history = HistorySync.objects.create(company=company, sync_date=timezone.now())
|
||||||
for row in csv_reader:
|
for row in csv_reader:
|
||||||
# trim strings
|
# trim strings
|
||||||
for key in row:
|
for key in row:
|
||||||
|
|||||||
@@ -72,10 +72,7 @@ class MyProductsViewSet(viewsets.ModelViewSet):
|
|||||||
permission_classes = [IsAuthenticated]
|
permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.model.objects.filter(creator=self.request.user)
|
return self.model.objects.filter(company=self.request.user.company).order_by('-created')
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
|
||||||
serializer.save(creator=self.request.user)
|
|
||||||
|
|
||||||
|
|
||||||
class AdminProductsViewSet(viewsets.ModelViewSet):
|
class AdminProductsViewSet(viewsets.ModelViewSet):
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class TrackUserViewTest(APITestCase):
|
|||||||
'model': 'company',
|
'model': 'company',
|
||||||
'id': company.id,
|
'id': company.id,
|
||||||
},
|
},
|
||||||
'geo': (12.2, -0.545)
|
'geo': {'latitude': 12.2, 'longitude': -0.545}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Query endpoint
|
# Query endpoint
|
||||||
|
|||||||
@@ -52,13 +52,18 @@ def track_user(request):
|
|||||||
try:
|
try:
|
||||||
data = json.loads(request.body)
|
data = json.loads(request.body)
|
||||||
|
|
||||||
|
if data.get('geo'):
|
||||||
|
coordinates = (data['geo'].get('latitude'), data['geo'].get('longitude'))
|
||||||
|
else:
|
||||||
|
coordinates = None
|
||||||
|
|
||||||
# gather instance data
|
# gather instance data
|
||||||
instance_data = {
|
instance_data = {
|
||||||
'action_object': data.get('action_object'),
|
'action_object': data.get('action_object'),
|
||||||
'user': None if request.user.is_anonymous else request.user,
|
'user': None if request.user.is_anonymous else request.user,
|
||||||
'anonymous': request.user.is_anonymous,
|
'anonymous': request.user.is_anonymous,
|
||||||
'ip_address': data.get('ip'),
|
'ip_address': data.get('ip'),
|
||||||
'geo': Point(data.get('geo')['latitude'], data.get('geo')['longitude']),
|
'geo': Point(coordinates),
|
||||||
}
|
}
|
||||||
|
|
||||||
if data['action_object'].get('model') == 'product':
|
if data['action_object'].get('model') == 'product':
|
||||||
@@ -76,4 +81,4 @@ def track_user(request):
|
|||||||
return Response(status=status.HTTP_201_CREATED)
|
return Response(status=status.HTTP_201_CREATED)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Stats could not be created: {str(e)}")
|
logging.error(f"Stats could not be created: {str(e)}")
|
||||||
return Response(f"Process could not be registered: {str(type(e))}", status=status.HTTP_406_NOT_ACCEPTABLE)
|
return Response(f"Process could not be registered [{str(type(e))}]: {str(e)}", status=status.HTTP_406_NOT_ACCEPTABLE)
|
||||||
|
|||||||
Reference in New Issue
Block a user