-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from Abramov0Alexandr/feature
Feature
- Loading branch information
Showing
16 changed files
with
403 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[flake8] | ||
|
||
max-line-length = 120 | ||
|
||
exclude = | ||
# The autogenerated migrations data, ignore it | ||
migrations | ||
|
||
# Excluding virtual env folders | ||
.venv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Generated by Django 4.2.5 on 2023-09-28 22:09 | ||
|
||
import custom_user.services | ||
import custom_user.user_manager | ||
from django.db import migrations, models | ||
import django.utils.timezone | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
('auth', '0012_alter_user_first_name_max_length'), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='CustomUser', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('password', models.CharField(max_length=128, verbose_name='password')), | ||
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), | ||
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), | ||
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), | ||
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), | ||
('first_name', models.CharField(blank=True, max_length=150, null=True, verbose_name='Имя')), | ||
('last_name', models.CharField(blank=True, max_length=150, null=True, verbose_name='Фамилия')), | ||
('patronymic', models.CharField(blank=True, max_length=150, null=True, verbose_name='Отчество')), | ||
('phone', models.CharField(blank=True, max_length=20, null=True, verbose_name='Телефон')), | ||
('shop_name', models.CharField(blank=True, max_length=200, null=True, verbose_name='Название магазина')), | ||
('shop_preview', models.ImageField(blank=True, null=True, upload_to=custom_user.services.shop_preview_upload_path, verbose_name='Превью магазина')), | ||
('email', models.EmailField(max_length=254, unique=True, verbose_name='Email')), | ||
('is_active', models.BooleanField(default=True, verbose_name='Статус активации')), | ||
('is_seller', models.BooleanField(choices=[(0, 'Посетитель'), (1, 'Продавец')], default=0, verbose_name='Статус клиента')), | ||
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), | ||
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), | ||
], | ||
options={ | ||
'verbose_name': 'user', | ||
'verbose_name_plural': 'users', | ||
'abstract': False, | ||
}, | ||
managers=[ | ||
('objects', custom_user.user_manager.CustomUserManager()), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from rest_framework import status | ||
from rest_framework.reverse import reverse | ||
from rest_framework.test import APITestCase | ||
|
||
|
||
class CommonUserCreate(APITestCase): | ||
|
||
def test_success_creation(self): | ||
"""Тесткейс успешного создания нового пользователя""" | ||
|
||
users_data: dict = { | ||
"first_name": "Alex", | ||
"last_name": "Abramov", | ||
"email": "common@user.ru", | ||
"phone": "800000000", | ||
"password": "123654", | ||
"password_confirmation": "123654" | ||
} | ||
|
||
response = self.client.post(reverse('custom_user:custom_user_create'), data=users_data) | ||
|
||
self.assertEqual(response.status_code, 200) | ||
self.assertEqual(response.json(), | ||
{'message': 'Регистрация успешно завершена!', | ||
'status': status.HTTP_201_CREATED}) | ||
|
||
def test_failed_password_confirmation(self): | ||
"""Тесткейс при неверной передачи значения password_confirmation""" | ||
|
||
users_data: dict = { | ||
"first_name": "Ivan", | ||
"last_name": "Ivanov", | ||
"email": "common@user.ru", | ||
"phone": "800000000", | ||
"password": "123654", | ||
"password_confirmation": "000000" | ||
} | ||
|
||
response = self.client.post(reverse('custom_user:custom_user_create'), data=users_data) | ||
|
||
self.assertEqual(response.status_code, 400) | ||
self.assertEqual(response.json(), | ||
{'non_field_errors': ['Пароль и его подтверждение не совпадают']}) | ||
|
||
def test_no_password_confirmation(self): | ||
"""Тесткейс при отсутствии значения password_confirmation""" | ||
|
||
users_data: dict = { | ||
"first_name": "Ivan", | ||
"last_name": "Ivanov", | ||
"email": "common@user.ru", | ||
"phone": "800000000", | ||
"password": "123654" | ||
} | ||
|
||
response = self.client.post(reverse('custom_user:custom_user_create'), data=users_data) | ||
|
||
self.assertEqual(response.status_code, 400) | ||
self.assertEqual(response.json(), | ||
{'password_confirmation': ['Обязательное поле.']}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from rest_framework import status | ||
from rest_framework.reverse import reverse | ||
from rest_framework.test import APITestCase | ||
|
||
|
||
class CommonUserCreateTestCase(APITestCase): | ||
|
||
def test_success_creation(self): | ||
"""Тесткейс успешного создания нового продавца""" | ||
|
||
seller_data: dict = { | ||
"is_seller": True, | ||
"shop_name": "ASOS", | ||
"email": "asos@shop.com", | ||
"password": "123654", | ||
"password_confirmation": "123654" | ||
} | ||
|
||
response = self.client.post(reverse('custom_user:custom_user_create'), data=seller_data) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
self.assertEqual(response.json(), | ||
{'message': 'Вы зарегистрированы в качестве продавца и можете размещать товары на площадке', | ||
'shop_title': 'ASOS', | ||
'status': 201}) | ||
|
||
def test_failed_password_confirmation(self): | ||
"""Тесткейс при неверной передачи значения password_confirmation""" | ||
|
||
seller_data: dict = { | ||
"is_seller": True, | ||
"shop_name": "ASOS", | ||
"email": "asos@shop.com", | ||
"password": "123654", | ||
"password_confirmation": "000000" | ||
} | ||
|
||
response = self.client.post(reverse('custom_user:custom_user_create'), data=seller_data) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) | ||
self.assertEqual(response.json(), | ||
{'non_field_errors': ['Пароль и его подтверждение не совпадают']}) | ||
|
||
def test_no_password_confirmation(self): | ||
"""Тесткейс при отсутствии значения password_confirmation""" | ||
|
||
seller_data: dict = { | ||
"is_seller": True, | ||
"shop_name": "ASOS", | ||
"email": "asos@shop.com", | ||
"password": "123654", | ||
} | ||
|
||
response = self.client.post(reverse('custom_user:custom_user_create'), data=seller_data) | ||
|
||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) | ||
self.assertEqual(response.json(), | ||
{'password_confirmation': ['Обязательное поле.']}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Generated by Django 4.2.5 on 2023-09-28 22:09 | ||
|
||
from django.conf import settings | ||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='Product', | ||
fields=[ | ||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('product_title', models.CharField(max_length=255, verbose_name='Наименование товара')), | ||
('price', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Цена товара')), | ||
('is_active_sale', models.BooleanField(choices=[(True, 'В продаже'), (False, 'Снят с продажи')], default=True, verbose_name='Статус товара')), | ||
('seller', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='seller', to=settings.AUTH_USER_MODEL, verbose_name='Продавец')), | ||
], | ||
options={ | ||
'verbose_name': 'Товар', | ||
'verbose_name_plural': 'Товары', | ||
}, | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from rest_framework import status | ||
from rest_framework.test import APITestCase, APIClient | ||
from custom_user.models import CustomUser | ||
from products.models import Product | ||
|
||
|
||
class ProductChangeSaleStatusTestCase(APITestCase): | ||
|
||
def setUp(self) -> None: | ||
"""Предварительное наполнение БД для дальнейших тестов.""" | ||
|
||
self.seller = CustomUser.objects.create( | ||
is_seller=True, | ||
shop_name='ASOS', | ||
email='asos@shop.com', | ||
password='123654' | ||
) | ||
|
||
self.product = Product.objects.create( | ||
seller=self.seller, | ||
product_title='Product Title', | ||
price='1000.00' | ||
) | ||
|
||
"""Имитация авторизации пользователя по JWT токену.""" | ||
self.client = APIClient() | ||
self.client.force_authenticate(user=self.seller) | ||
|
||
def test_change_status(self): | ||
|
||
response = self.client.patch(f'/products/change_status/{self.product.id}/') | ||
|
||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
|
||
self.assertEqual(response.json(), | ||
{"Product info": { | ||
"sale status": "False", | ||
"message": "Product Title снят с продажи", | ||
"status": 200 | ||
}}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from rest_framework import status | ||
from rest_framework.test import APITestCase, APIClient | ||
from custom_user.models import CustomUser | ||
from products.models import Product | ||
|
||
|
||
class ProductDetailTestCase(APITestCase): | ||
|
||
def setUp(self) -> None: | ||
"""Предварительное наполнение БД для дальнейших тестов.""" | ||
|
||
self.seller = CustomUser.objects.create( | ||
is_seller=True, | ||
shop_name='ASOS', | ||
email='asos@shop.com', | ||
password='123654' | ||
) | ||
|
||
self.product = Product.objects.create( | ||
seller=self.seller, | ||
product_title='Product Title', | ||
price='1000.00' | ||
) | ||
|
||
"""Имитация авторизации пользователя по JWT токену.""" | ||
self.client = APIClient() | ||
self.client.force_authenticate(user=self.seller) | ||
|
||
def test_retrieve_product(self): | ||
|
||
response = self.client.get(f'/products/detail/{self.product.id}/') | ||
|
||
self.assertEqual(response.status_code, status.HTTP_200_OK) | ||
|
||
self.assertEqual(response.json(), | ||
{'id': self.product.id, | ||
'shop_title': self.seller.shop_name, | ||
'seller': self.seller.email, | ||
'product_title': self.product.product_title, | ||
'price': self.product.price, | ||
'is_active_sale': True} | ||
) |
Oops, something went wrong.