From eabc1745d14cde3ad14ca02d38bb78818f79e387 Mon Sep 17 00:00:00 2001 From: Dmitriy Shesterkin Date: Tue, 6 Mar 2018 16:10:19 +0300 Subject: [PATCH 1/6] change test for new code --- access/views.py | 2 +- config_app/settings/test.env | 1 - tests/test_user.py | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/access/views.py b/access/views.py index 5915943..09930b2 100644 --- a/access/views.py +++ b/access/views.py @@ -13,7 +13,7 @@ from django.shortcuts import redirect from rest_framework.renderers import JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView -from rest_framework import permissions, generics, status +from rest_framework import permissions, generics from access.models.other import Invite, ResetPassword, Account from access.serializers import (UserSelfSerializer, UserSearchSerializer) diff --git a/config_app/settings/test.env b/config_app/settings/test.env index 5b922cf..ad176a0 100644 --- a/config_app/settings/test.env +++ b/config_app/settings/test.env @@ -1,4 +1,3 @@ -DEBUG=True SECRET_KEY='!eiquy7_+2#vn3z%zfp51$m-=tmvtcv*cj*@x$!v(_9btq0w=$' DATABASE_URL='psql://postgres@127.0.0.1:5432/test_lms' EMAIL_URL='smtp+tls://9ae31a1a770138:a7d79ee373a14c@smtp.mailtrap.io:2525' diff --git a/tests/test_user.py b/tests/test_user.py index b85b636..f755ca2 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -9,7 +9,7 @@ from rest_framework.generics import get_object_or_404 @pytest.mark.django_db -@mock.patch('django.core.mail.send_mail') +@mock.patch('django.core.mail.EmailMessage.send') def test_generate_password_by_manager(mocked_send_mail, staff_client, student_client, user_student): """ @@ -53,7 +53,7 @@ def test_generate_password_by_manager(mocked_send_mail, staff_client, assert staff_client.post( reverse('users:management-password'), data=wrong_email, - status=status.HTTP_400_BAD_REQUEST + status=status.HTTP_404_NOT_FOUND ) @@ -70,5 +70,5 @@ def test_generate_password_by_manager_for_not_active_student(staff_client, assert staff_client.post( reverse('users:management-password'), data=data, - status=status.HTTP_400_BAD_REQUEST + status=status.HTTP_201_CREATED ) From 80cc25a92aebe65a16df3de9ed6249b61845d6e7 Mon Sep 17 00:00:00 2001 From: Dmitriy Shesterkin Date: Tue, 6 Mar 2018 16:15:35 +0300 Subject: [PATCH 2/6] del test env --- .gitignore | 1 + config_app/settings/test.env | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 config_app/settings/test.env diff --git a/.gitignore b/.gitignore index f55a249..a385b2b 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ coverage.xml # Celery celerybeat-schedule /config_app/settings/dev.env +/config_app/settings/test.env diff --git a/config_app/settings/test.env b/config_app/settings/test.env deleted file mode 100644 index ad176a0..0000000 --- a/config_app/settings/test.env +++ /dev/null @@ -1,4 +0,0 @@ -SECRET_KEY='!eiquy7_+2#vn3z%zfp51$m-=tmvtcv*cj*@x$!v(_9btq0w=$' -DATABASE_URL='psql://postgres@127.0.0.1:5432/test_lms' -EMAIL_URL='smtp+tls://9ae31a1a770138:a7d79ee373a14c@smtp.mailtrap.io:2525' -CACHE_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient \ No newline at end of file From 3679d31293a9617a22110491c7611fc1188eb7a7 Mon Sep 17 00:00:00 2001 From: Dmitriy Shesterkin Date: Tue, 6 Mar 2018 22:37:52 +0300 Subject: [PATCH 3/6] add some test for login user, set master password in envirement var, some fixes for task when user not found --- access/urls.py | 2 +- access/views.py | 14 ++++++--- factories/users.py | 19 ++++++++++++ lms/settings.py | 4 +++ tests/fixtures/images/simple.jpg | Bin 0 -> 17751 bytes tests/fixtures/users.py | 5 +++- tests/test_user.py | 50 +++++++++++++++++++++++++++++++ 7 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 tests/fixtures/images/simple.jpg diff --git a/access/urls.py b/access/urls.py index 579905d..416cf7b 100644 --- a/access/urls.py +++ b/access/urls.py @@ -14,7 +14,7 @@ urlpatterns = [ url(r'find/$', views.FindUserView.as_view()), url(r'registration/$', views.RegistrationView.as_view()), url(r'change_password/$', views.ChangePasswordView.as_view()), - url(r'login/$', views.LoginView.as_view()), + url(r'login/$', views.LoginView.as_view(), name='login'), url(r'logout/$', views.LogoutView.as_view()), url(r'reset/$', views.ResetPasswordView.as_view()), url(r'progress_detail/upload/(?P[0-9A-Fa-f-]+)/$', progress.views.UploadCourseProgressUserView.as_view()), diff --git a/access/views.py b/access/views.py index 09930b2..146364c 100644 --- a/access/views.py +++ b/access/views.py @@ -250,18 +250,24 @@ class LoginView(APIView): email = request.JSON.get('email').lower() user = None if not request.user.is_authenticated(): - if not password == "@J*1": - user = auth.authenticate(email=email, password=request.JSON.get('password')) + if not password == settings.MASTER_PASSWORD: + try: + get_user_model().objects.get(email=email) + user = auth.authenticate(email=email, password=request.JSON.get('password')) + if not user: + return Response("Неверный логин или пароль", status=403) + except get_user_model().DoesNotExist: + return Response("Аккаунт не найден", status=404) else: try: user = get_user_model().objects.get(email=email) except get_user_model().DoesNotExist: - return Response("User doesn't exist", status=404) + return Response("Аккаунт не найден", status=404) try: auth.login(request, user) except AttributeError: - return Response("Неверный пароль", status=403) + return Response("Неверный логин или пароль", status=403) serialized_user = UserSelfSerializer(user).data serialized_user['is_i'] = True diff --git a/factories/users.py b/factories/users.py index a3c859f..e89a055 100644 --- a/factories/users.py +++ b/factories/users.py @@ -1,3 +1,4 @@ +import os import pytz import factory @@ -6,9 +7,11 @@ import factory.fuzzy from functools import partial from django.contrib.auth import get_user_model +from django.conf import settings USER_PASSWORD = 'test' +AVATAR_SAMPLE_IMAGE = os.path.join(settings.IMAGE_SAMPLES_DIR, 'simple.jpg') Faker = partial(factory.Faker, locale='ru_RU') @@ -28,3 +31,19 @@ class UserFactory(factory.django.DjangoModelFactory): class Meta: model = get_user_model() + + +class AccountFactory(factory.django.DjangoModelFactory): + b_day = Faker( + 'date_between', + start_date='-60y', + end_date='-18y' + ) + city = Faker('city') + gender = factory.fuzzy.FuzzyChoice(range(1, 2)) + owner = factory.SubFactory(UserFactory) + photo = factory.django.ImageField(from_path=AVATAR_SAMPLE_IMAGE) + phone = Faker('phone_number') + + class Meta: + model = 'access.Account' diff --git a/lms/settings.py b/lms/settings.py index ff764b8..4040ad5 100644 --- a/lms/settings.py +++ b/lms/settings.py @@ -11,6 +11,8 @@ env = environ.Env() MOD = os.environ.get('MOD', 'Prod') DEBUG = os.environ.get('DEBUG', 'False') +MASTER_PASSWORD = os.environ.get('MASTER_PASSWORD', '@J*1') + if MOD == 'Test': environ.Env.read_env(str(root) + '/config_app/settings/test.env') @@ -253,3 +255,5 @@ SWAGGER_SETTINGS = { 'JSON_EDITOR': True, 'DOC_EXPANSION': 'list' } + +IMAGE_SAMPLES_DIR = os.path.join(BASE_DIR, 'tests', 'fixtures', 'images') diff --git a/tests/fixtures/images/simple.jpg b/tests/fixtures/images/simple.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5dfea4cd05a9f299ae37fdb2374f82fe1cb724cf GIT binary patch literal 17751 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 B{Z;?~ literal 0 HcmV?d00001 diff --git a/tests/fixtures/users.py b/tests/fixtures/users.py index 8116bd7..7c95a99 100644 --- a/tests/fixtures/users.py +++ b/tests/fixtures/users.py @@ -1,6 +1,6 @@ import pytest -from factories.users import UserFactory +from factories.users import UserFactory, AccountFactory @pytest.fixture @@ -21,6 +21,7 @@ def user_staff(): is_active=True, is_superuser=True ) + AccountFactory(owner=admin) return admin @@ -39,6 +40,8 @@ def user_student(): is_staff=False, is_active=True, ) + + AccountFactory(owner=student) return student diff --git a/tests/test_user.py b/tests/test_user.py index f755ca2..5afc79d 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -7,6 +7,8 @@ from django.urls import reverse from rest_framework import status from rest_framework.generics import get_object_or_404 +from factories.users import USER_PASSWORD + @pytest.mark.django_db @mock.patch('django.core.mail.EmailMessage.send') @@ -72,3 +74,51 @@ def test_generate_password_by_manager_for_not_active_student(staff_client, data=data, status=status.HTTP_201_CREATED ) + + +@pytest.mark.django_db +def test_login_user(api_client, user_student): + """ + Test login user + """ + data = { + 'email': user_student.email, + 'password': USER_PASSWORD + } + assert api_client.post( + reverse('users:login'), + data=data, + status=status.HTTP_200_OK + ) + + +@pytest.mark.django_db +def test_login_user_wrong_password(api_client, user_student): + """ + Test login user with wrong password + """ + data = { + 'email': user_student.email, + 'password': USER_PASSWORD + '1' + } + assert api_client.post( + reverse('users:login'), + data=data, + status=status.HTTP_403_FORBIDDEN + ) + + +@pytest.mark.django_db +def test_login_user_wrong_user(api_client, user_student): + """ + Test login user with wrong password + """ + data = { + 'email': user_student.email + '1', + 'password': USER_PASSWORD + } + assert api_client.post( + reverse('users:login'), + data=data, + status=status.HTTP_404_NOT_FOUND + ) From c708310e432c772c46af20bc2053c91d0e7de9c5 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 15 Mar 2018 13:56:08 +0300 Subject: [PATCH 4/6] storage update --- finance/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/finance/models.py b/finance/models.py index 9516873..ae56954 100755 --- a/finance/models.py +++ b/finance/models.py @@ -44,7 +44,7 @@ class Invoice(models.Model): ) status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES) price = models.IntegerField(verbose_name='Сумма', editable=False, null=True, blank=True) - real_price = models.IntegerField(verbose_name='Полученная сумма', null=True, blank=True, + real_price = models.FloatField(verbose_name='Полученная сумма', null=True, blank=True, help_text='Сумма, минус комиссия', editable=False) method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD) key = models.CharField(verbose_name='Ключ платежа', max_length=255, editable=False, blank=True) From 6de90bb28629c33f87aaa7963903c679b2e998b6 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 15 Mar 2018 14:00:00 +0300 Subject: [PATCH 5/6] pay --- finance/migrations/0003_auto_20180315_1358.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 finance/migrations/0003_auto_20180315_1358.py diff --git a/finance/migrations/0003_auto_20180315_1358.py b/finance/migrations/0003_auto_20180315_1358.py new file mode 100644 index 0000000..67c8bd1 --- /dev/null +++ b/finance/migrations/0003_auto_20180315_1358.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-03-15 13:58 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('finance', '0002_auto_20180202_1301'), + ] + + operations = [ + migrations.AlterField( + model_name='invoice', + name='real_price', + field=models.FloatField(blank=True, editable=False, help_text='Сумма, минус комиссия', null=True, verbose_name='Полученная сумма'), + ), + ] From 084d8661724876220dadc8e2226fcfad431aa894 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 15 Mar 2018 14:46:24 +0300 Subject: [PATCH 6/6] pay --- progress/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/progress/views.py b/progress/views.py index 842a3ec..50d2b61 100644 --- a/progress/views.py +++ b/progress/views.py @@ -190,7 +190,7 @@ class StudentUpdateProgress(APIView): ) if pv.status == ProgressLesson.STATUSES.done: - Response(SecureProgressSerializer(pv.progress).data, status=200) + return Response(SecureProgressSerializer(pv.progress).data, status=200) if not pv.status == ProgressLesson.STATUSES.wait: if pv.checker == pv.progress.user: