Merge remote-tracking branch 'origin/dev' into pm_payments_repeat

# Conflicts:
#	finance/views.py
remotes/origin/yandex_rebiling
Evgeniy Shabanov 8 years ago
commit 55ace09705
  1. 1
      .gitignore
  2. 2
      access/urls.py
  3. 16
      access/views.py
  4. 5
      config_app/settings/test.env
  5. 2
      courses/views.py
  6. 19
      factories/users.py
  7. 20
      finance/migrations/0003_auto_20180315_1358.py
  8. 2
      finance/models.py
  9. 5
      finance/signals.py
  10. 150
      finance/views.py
  11. 4
      lms/settings.py
  12. 4
      progress/views.py
  13. BIN
      tests/fixtures/images/simple.jpg
  14. 5
      tests/fixtures/users.py
  15. 56
      tests/test_user.py

1
.gitignore vendored

@ -37,3 +37,4 @@ coverage.xml
# Celery # Celery
celerybeat-schedule celerybeat-schedule
/config_app/settings/dev.env /config_app/settings/dev.env
/config_app/settings/test.env

@ -14,7 +14,7 @@ urlpatterns = [
url(r'find/$', views.FindUserView.as_view()), url(r'find/$', views.FindUserView.as_view()),
url(r'registration/$', views.RegistrationView.as_view()), url(r'registration/$', views.RegistrationView.as_view()),
url(r'change_password/$', views.ChangePasswordView.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'logout/$', views.LogoutView.as_view()),
url(r'reset/$', views.ResetPasswordView.as_view()), url(r'reset/$', views.ResetPasswordView.as_view()),
url(r'progress_detail/upload/(?P<token>[0-9A-Fa-f-]+)/$', progress.views.UploadCourseProgressUserView.as_view()), url(r'progress_detail/upload/(?P<token>[0-9A-Fa-f-]+)/$', progress.views.UploadCourseProgressUserView.as_view()),

@ -13,7 +13,7 @@ from django.shortcuts import redirect
from rest_framework.renderers import JSONRenderer from rest_framework.renderers import JSONRenderer
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView 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.models.other import Invite, ResetPassword, Account
from access.serializers import (UserSelfSerializer, UserSearchSerializer) from access.serializers import (UserSelfSerializer, UserSearchSerializer)
@ -250,18 +250,24 @@ class LoginView(APIView):
email = request.JSON.get('email').lower() email = request.JSON.get('email').lower()
user = None user = None
if not request.user.is_authenticated(): if not request.user.is_authenticated():
if not password == "@J*1": if not password == settings.MASTER_PASSWORD:
user = auth.authenticate(email=email, password=request.JSON.get('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: else:
try: try:
user = get_user_model().objects.get(email=email) user = get_user_model().objects.get(email=email)
except get_user_model().DoesNotExist: except get_user_model().DoesNotExist:
return Response("User doesn't exist", status=404) return Response("Аккаунт не найден", status=404)
try: try:
auth.login(request, user) auth.login(request, user)
except AttributeError: except AttributeError:
return Response("Неверный пароль", status=403) return Response("Неверный логин или пароль", status=403)
serialized_user = UserSelfSerializer(user).data serialized_user = UserSelfSerializer(user).data
serialized_user['is_i'] = True serialized_user['is_i'] = True

@ -1,5 +0,0 @@
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'
CACHE_URL=rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient

@ -89,7 +89,7 @@ class LessonInfoView(APIView):
lesson = Lesson.objects.get(token=token) lesson = Lesson.objects.get(token=token)
except Lesson.DoesNotExist: except Lesson.DoesNotExist:
return Response('Урок не найден', status=404) return Response('Урок не найден', status=404)
if request.user.is_authenticated and request.user.out_key in lesson.topic.course.teacher_tokens: if request.user.is_authenticated:
return Response(TeacherLessonSerializer(lesson).data, self.status_code) return Response(TeacherLessonSerializer(lesson).data, self.status_code)
return Response("Пользователь не является преподователем по курсу", status=403) return Response("Пользователь не является преподователем по курсу", status=403)

@ -1,3 +1,4 @@
import os
import pytz import pytz
import factory import factory
@ -6,9 +7,11 @@ import factory.fuzzy
from functools import partial from functools import partial
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.conf import settings
USER_PASSWORD = 'test' USER_PASSWORD = 'test'
AVATAR_SAMPLE_IMAGE = os.path.join(settings.IMAGE_SAMPLES_DIR, 'simple.jpg')
Faker = partial(factory.Faker, locale='ru_RU') Faker = partial(factory.Faker, locale='ru_RU')
@ -28,3 +31,19 @@ class UserFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = get_user_model() 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'

@ -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='Полученная сумма'),
),
]

@ -44,7 +44,7 @@ class Invoice(models.Model):
) )
status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES) status = models.CharField(verbose_name='Статус', max_length=1, default='W', choices=BILL_STATUSES)
price = models.IntegerField(verbose_name='Сумма', editable=False, null=True, blank=True) 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) help_text='Сумма, минус комиссия', editable=False)
method = models.CharField(verbose_name='Способ оплаты', max_length=2, default='Y', choices=BILL_METHOD) 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) key = models.CharField(verbose_name='Ключ платежа', max_length=255, editable=False, blank=True)

@ -36,7 +36,7 @@ def invoice_signal(instance, **kwargs):
user=instance.bill.user, user=instance.bill.user,
) )
except Progress.DoesNotExist: except Progress.DoesNotExist:
p=Progress.objects.create( p = Progress.objects.create(
course_token=instance.bill.course_token, course_token=instance.bill.course_token,
user=instance.bill.user, user=instance.bill.user,
teacher=get_user_model().objects.get(out_key=course.get_teacher()) teacher=get_user_model().objects.get(out_key=course.get_teacher())
@ -54,6 +54,7 @@ def invoice_signal(instance, **kwargs):
% (course.title, settings.DOMAIN, course.slug), % (course.title, settings.DOMAIN, course.slug),
'robo@skillbox.ru', 'robo@skillbox.ru',
[instance.bill.user.email], [instance.bill.user.email],
bcc=[instance.bill.opener.email],
reply_to=[instance.bill.opener.email], reply_to=[instance.bill.opener.email],
) )
else: else:
@ -62,7 +63,7 @@ def invoice_signal(instance, **kwargs):
'''Курс "%s" был забронирован''' % course.title, '''Курс "%s" был забронирован''' % course.title,
'robo@skillbox.ru', 'robo@skillbox.ru',
[instance.bill.user.email], [instance.bill.user.email],
cc=[instance.bill.opener.email], bcc=[instance.bill.opener.email],
reply_to=[instance.bill.opener.email], reply_to=[instance.bill.opener.email],
) )
msg.send() msg.send()

@ -1,10 +1,9 @@
import csv import csv
import logging import logging
import datetime
import dicttoxml
import requests import requests
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.mail import EmailMessage
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse, HttpResponseForbidden from django.http import HttpResponse, HttpResponseForbidden
from django.shortcuts import redirect from django.shortcuts import redirect
@ -14,6 +13,7 @@ from rest_framework.views import APIView
from yandex_money.models import Payment from yandex_money.models import Payment
from django.conf import settings from django.conf import settings
from courses.models import Course
from courses.api import CourseParamsApi from courses.api import CourseParamsApi
from finance.models import Bill, Invoice from finance.models import Bill, Invoice
from finance.serializers import BillSerializer, InvoiceSerializer from finance.serializers import BillSerializer, InvoiceSerializer
@ -43,24 +43,46 @@ class BillListView(APIView):
or request.user.is_superuser): or request.user.is_superuser):
bill = request.JSON.get('bill') bill = request.JSON.get('bill')
children = request.JSON.get('children', []) children = request.JSON.get('children', [])
bill_kwarg = dict()
if bill: if bill:
bill_kwarg['user'] = get_user_model().objects.get(email=bill['user']) user = get_user_model().objects.get(email=bill['user'])
bill_kwarg['opener'] = get_user_model().objects.get(email=bill['opener']) opener = get_user_model().objects.get(email=bill['opener'])
bill_kwarg['description'] = bill['description'] description = bill['description']
bill_kwarg['comment'] = bill['comment'] comment = bill['comment']
bill_kwarg['course_token'] = bill['course_token'] course_token = bill['course_token']
bill_obj, is_create = Bill.objects.update_or_create(**bill_kwarg) try:
invoices = bill_obj.invoice_set.all() bill_obj = Bill.objects.get(user=user, course_token=course_token)
except Bill.DoesNotExist:
bill_obj = Bill.objects.create(user=user, course_token=course_token)
bill_obj.opener = opener
bill_obj.description = description
bill_obj.comment = comment
bill_obj.save()
for i in children: for i in children:
i['method'] = get_real_name(elem=i['method'], array=Invoice.BILL_METHOD) status = get_real_name(elem=i['status'], array=Invoice.BILL_STATUSES)
i['status'] = get_real_name(elem=i['status'], array=Invoice.BILL_STATUSES) try:
i['bill'] = bill_obj invoice_id = i['id']
i['yandex_pay'] = None except KeyError:
invoice, _is_create = Invoice.objects.update_or_create(**i) invoice_id = None
try:
if not invoice_id is None:
invoice = Invoice.objects.get(id=i['id'])
if invoice.status == "P" or invoice.status == status:
continue
else:
raise Invoice.DoesNotExist
except Invoice.DoesNotExist:
i['method'] = get_real_name(elem=i['method'], array=Invoice.BILL_METHOD)
i['status'] = status
i['bill'] = bill_obj
i['yandex_pay'] = None
invoice = Invoice.objects.create(**i)
if i['method'] == 'Y' and invoice.yandex_pay is None: if i['method'] == 'Y' and invoice.yandex_pay is None:
yandex_pay = Payment.objects.create( yandex_pay = Payment.objects.create(
order_amount=i['price'], order_amount=i['price'],
@ -72,9 +94,20 @@ class BillListView(APIView):
invoice.yandex_pay = yandex_pay invoice.yandex_pay = yandex_pay
invoice.save() invoice.save()
invoices = [j for j in invoices if not j.id == invoice.id] msg = EmailMessage(
'Выставлен новый счёт.',
[i.delete() for i in invoices] '''Менеджер %s выставил счёт пользователю %s на курс "%s".'''
% (
invoice.bill.opener.get_full_name(),
invoice.bill.user.email,
Course.objects.get(token=invoice.bill.course_token).title,
),
'robo@skillbox.ru',
[invoice.bill.opener.email],
bcc=['dmitry.dolya@skillbox.ru'],
)
msg.send()
res = { res = {
"bill": BillSerializer(bill_obj).data, "bill": BillSerializer(bill_obj).data,
@ -161,6 +194,17 @@ class YandexPay(APIView):
'shopFailURL': settings.YANDEX_MONEY_FAIL_URL, 'shopFailURL': settings.YANDEX_MONEY_FAIL_URL,
}) })
msg = EmailMessage(
'Пользователь перешёл на страницу оплаты.',
'''Пользователь "%s" перешёл на страницу оплаты курса "%s".'''
% (pay.invoice.bill.user.email, Course.objects.get(token=pay.invoice.bill.course_token).title),
'robo@skillbox.ru',
[pay.invoice.bill.opener.email],
bcc=['dmitry.dolya@skillbox.ru'],
)
msg.send()
return redirect(r.url) return redirect(r.url)
except Payment.DoesNotExist: except Payment.DoesNotExist:
@ -179,8 +223,8 @@ def get_invoices(request):
file_name = file_name + "__to_%s" % date_to if date_to else file_name file_name = file_name + "__to_%s" % date_to if date_to else file_name
invoices = Invoice.objects.filter(method="Y", status="F") invoices = Invoice.objects.filter(method="Y", status="F")
invoices = invoices.filter(date__lt=date_to) if date_to else invoices invoices = invoices.filter(yandex_pay__performed_datetime__lt=date_to) if date_to else invoices
invoices = invoices.filter(date__gte=date_from) if date_from else invoices invoices = invoices.filter(yandex_pay__performed_datetime__gte=date_from) if date_from else invoices
response = HttpResponse(content_type='text/csv') response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="%s.csv"' % file_name response['Content-Disposition'] = 'attachment; filename="%s.csv"' % file_name
@ -191,8 +235,8 @@ def get_invoices(request):
for i in invoices.order_by('-date'): for i in invoices.order_by('-date'):
course_api = CourseParamsApi(i.bill.course_token) course_api = CourseParamsApi(i.bill.course_token)
writer.writerow([ writer.writerow([
i.date.date(), i.yandex_pay.performed_datetime.date(),
i.date.time(), i.yandex_pay.performed_datetime.time(),
i.bill.user.email, i.bill.user.email,
i.bill.user.get_full_name(), i.bill.user.get_full_name(),
course_api.get_slug_and_title()['title'], course_api.get_slug_and_title()['title'],
@ -215,33 +259,43 @@ class YandexCheckView(APIView):
val = i.split('=')[1] val = i.split('=')[1]
data[key] = val data[key] = val
logger_yandex.info(data) logger_yandex.info('Проверка платежа запрос', exc_info=True, extra={
'request': data,
})
try: try:
pay = Payment.objects.get(order_number=data['orderNumber']) pay = Payment.objects.get(order_number=data['orderNumber'])
except Payment.DoesNotExist: except Payment.DoesNotExist:
logger_yandex.error("Payment with id=%s not found" % data['orderNumber']) logger_yandex.error('Ошибка проверки платежа', exc_info=True, extra={
'request': "Payment with id=%s not found" % data['orderNumber'],
})
return Response(status=204) return Response(status=204)
if not pay.status == Payment.STATUS.PROCESSED: if not pay.status == Payment.STATUS.PROCESSED:
logger_yandex.error("Payment with id=%s have status %s" % (data['orderNumber'], pay.status)) logger_yandex.error('Ошибка проверки платежа', exc_info=True, extra={
'request': "Payment with id=%s have status %s" % (data['orderNumber'], pay.status),
})
return Response(status=204) return Response(status=204)
if not pay.shop_id == int(data['shopId']): if not pay.shop_id == int(data['shopId']):
logger_yandex.error("ShopId=%s not match" % (data['shopId'],)) logger_yandex.error('Ошибка проверки платежа', exc_info=True, extra={
'request': "ShopId=%s not match" % (data['shopId'],),
})
return Response(status=204) return Response(status=204)
if not pay.scid == int(data['scid']): if not pay.scid == int(data['scid']):
logger_yandex.error("scid=%s not match" % (data['scid'],)) logger_yandex.error('Ошибка проверки платежа', exc_info=True, extra={
'request': "scid=%s not match" % (data['scid'],)
})
return Response(status=204) return Response(status=204)
if not pay.order_amount == float(data['orderSumAmount']): if not pay.order_amount == float(data['orderSumAmount']):
logger_yandex.error("Expected amount is %s received amount is %s" logger_yandex.error('Ошибка проверки платежа', exc_info=True, extra={
% (pay.order_amount, data['orderSumAmount'])) 'request': "Expected amount is %s received amount is %s"
% (pay.order_amount, data['orderSumAmount']),
})
return Response(status=204) return Response(status=204)
# TODO Нужно решение
# pay.invoice_id = int(data['invoiceId'])
# pay.save()
now = timezone.now() now = timezone.now()
pay.performed_datetime = now.isoformat() pay.performed_datetime = now.isoformat()
pay.save() pay.save()
@ -249,7 +303,9 @@ class YandexCheckView(APIView):
xml_res = """<checkOrderResponse performedDatetime="%s" code="0" invoiceId="%s" shopId="%s"/> xml_res = """<checkOrderResponse performedDatetime="%s" code="0" invoiceId="%s" shopId="%s"/>
""" % (pay.performed_datetime, str(data['invoiceId']), str(pay.shop_id)) """ % (pay.performed_datetime, str(data['invoiceId']), str(pay.shop_id))
logger_yandex.info(xml_res) logger_yandex.info('Проверка платежа ответ', exc_info=True, extra={
'response': xml_res,
})
return HttpResponse(xml_res, content_type='application/xml') return HttpResponse(xml_res, content_type='application/xml')
@ -268,19 +324,39 @@ class YandexAvisoView(APIView):
try: try:
pay = Payment.objects.get(order_number=data['orderNumber']) pay = Payment.objects.get(order_number=data['orderNumber'])
except Payment.DoesNotExist: except Payment.DoesNotExist:
logger_yandex.error("Payment with invoice_id=%s not found" % data['orderNumber']) logger_yandex.error('Ошибка подтверждения платежа', exc_info=True, extra={
'request': "Payment with invoice_id=%s not found" % data['orderNumber'],
})
return Response(status=204) return Response(status=204)
logger_yandex.info('Get success pay with invoice_id(yandex) %s' % pay.invoice_id) logger_yandex.info('Подтверждение платежа запрос', exc_info=True, extra={
'request': 'Get success pay with invoice_id(yandex) %s' % str(data['invoiceId']),
})
pay.shop_amount = data['shopSumAmount'] pay.shop_amount = data['shopSumAmount']
pay.status = Payment.STATUS.SUCCESS pay.status = Payment.STATUS.SUCCESS
pay.invoice_id = data['invoiceId'] pay.invoice_id = data['invoiceId']
now = timezone.now()
pay.performed_datetime = now.isoformat()
pay.save() pay.save()
xml_res = """<paymentAvisoResponse performedDatetime="%s" code="0" invoiceId="%s" shopId="%s"/> xml_res = """<paymentAvisoResponse performedDatetime="%s" code="0" invoiceId="%s" shopId="%s"/>
""" % (pay.performed_datetime, str(data['invoiceId']), str(pay.shop_id)) """ % (pay.performed_datetime, str(data['invoiceId']), str(pay.shop_id))
logger_yandex.info(xml_res) logger_yandex.info('Подтверждение платежа ответ', exc_info=True, extra={
'response': xml_res,
})
msg = EmailMessage(
'Успешная оплата.',
'''Пользователь "%s", перевёл %s рублей. Номер платежа в яндекс кассе %s'''
% (pay.invoice.bill.user.email, str(pay.invoice.price), str(data['invoiceId'])),
'robo@skillbox.ru',
[pay.invoice.bill.opener.email],
bcc=['dmitry.dolya@skillbox.ru', 'vera.procenko@skillbox.ru'],
)
msg.send()
if pay.invoice.rebilling_on: if pay.invoice.rebilling_on:
setup_periodic_billing(pay.order_number) setup_periodic_billing(pay.order_number)

@ -11,6 +11,8 @@ env = environ.Env()
MOD = os.environ.get('MOD', 'Prod') MOD = os.environ.get('MOD', 'Prod')
DEBUG = os.environ.get('DEBUG', 'False') DEBUG = os.environ.get('DEBUG', 'False')
MASTER_PASSWORD = os.environ.get('MASTER_PASSWORD', '@J*1')
if MOD == 'Test': if MOD == 'Test':
environ.Env.read_env(str(root) + '/config_app/settings/test.env') environ.Env.read_env(str(root) + '/config_app/settings/test.env')
@ -258,3 +260,5 @@ SWAGGER_SETTINGS = {
'JSON_EDITOR': True, 'JSON_EDITOR': True,
'DOC_EXPANSION': 'list' 'DOC_EXPANSION': 'list'
} }
IMAGE_SAMPLES_DIR = os.path.join(BASE_DIR, 'tests', 'fixtures', 'images')

@ -127,7 +127,7 @@ class TeacherUpdateProgress(APIView):
pv.status = ProgressLesson.STATUSES.fail pv.status = ProgressLesson.STATUSES.fail
msg = EmailMessage( msg = EmailMessage(
'Ваша работа отправлена на доработку', 'Ваша работа отправлена на доработку',
'''Преподователь "%s" отклонил вашу работу''' % request.user.get_full_name(), '''Преподаватель "%s" отклонил вашу работу''' % request.user.get_full_name(),
'robo@skillbox.ru', 'robo@skillbox.ru',
[student.email], [student.email],
) )
@ -190,7 +190,7 @@ class StudentUpdateProgress(APIView):
) )
if pv.status == ProgressLesson.STATUSES.done: 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 not pv.status == ProgressLesson.STATUSES.wait:
if pv.checker == pv.progress.user: if pv.checker == pv.progress.user:

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

@ -1,6 +1,6 @@
import pytest import pytest
from factories.users import UserFactory from factories.users import UserFactory, AccountFactory
@pytest.fixture @pytest.fixture
@ -21,6 +21,7 @@ def user_staff():
is_active=True, is_active=True,
is_superuser=True is_superuser=True
) )
AccountFactory(owner=admin)
return admin return admin
@ -39,6 +40,8 @@ def user_student():
is_staff=False, is_staff=False,
is_active=True, is_active=True,
) )
AccountFactory(owner=student)
return student return student

@ -7,9 +7,11 @@ from django.urls import reverse
from rest_framework import status from rest_framework import status
from rest_framework.generics import get_object_or_404 from rest_framework.generics import get_object_or_404
from factories.users import USER_PASSWORD
@pytest.mark.django_db @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, def test_generate_password_by_manager(mocked_send_mail, staff_client,
student_client, user_student): student_client, user_student):
""" """
@ -53,7 +55,7 @@ def test_generate_password_by_manager(mocked_send_mail, staff_client,
assert staff_client.post( assert staff_client.post(
reverse('users:management-password'), reverse('users:management-password'),
data=wrong_email, data=wrong_email,
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_404_NOT_FOUND
) )
@ -70,5 +72,53 @@ def test_generate_password_by_manager_for_not_active_student(staff_client,
assert staff_client.post( assert staff_client.post(
reverse('users:management-password'), reverse('users:management-password'),
data=data, data=data,
status=status.HTTP_400_BAD_REQUEST 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
) )

Loading…
Cancel
Save