Compare commits

...

8 Commits

  1. 1
      .gitignore
  2. 12
      access/factories.py
  3. 25
      access/groups.py
  4. 56
      access/tests/conftest.py
  5. 122
      access/tests/fixtures.py
  6. 120
      access/tests/test_access_view.py
  7. 4
      access/views.py
  8. 2
      api_v1/urls.py
  9. 62
      courses/factories.py
  10. 0
      courses/factories/__init__.py
  11. 18
      courses/tests/fixtures.py
  12. 0
      factories/__init__.py
  13. 72
      finance/factories.py
  14. 0
      finance/tests.py
  15. 58
      finance/tests/conftest.py
  16. 53
      finance/tests/fixtures.py
  17. 198
      finance/tests/test_finance_view.py
  18. 2
      finance/urls.py
  19. 2
      finance/views.py
  20. 2
      lms/settings.py
  21. 21
      lms/settings_qa.py
  22. 2
      pytest.ini
  23. 28
      tests/conftest.py
  24. 63
      tests/fixtures/users.py
  25. 124
      tests/test_user.py

1
.gitignore vendored

@ -38,3 +38,4 @@ coverage.xml
celerybeat-schedule celerybeat-schedule
/config_app/settings/dev.env /config_app/settings/dev.env
/config_app/settings/test.env /config_app/settings/test.env
/media_qa/

@ -11,7 +11,7 @@ from django.conf import settings
USER_PASSWORD = 'test' USER_PASSWORD = 'test'
AVATAR_SAMPLE_IMAGE = os.path.join(settings.IMAGE_SAMPLES_DIR, 'simple.jpg') 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')
@ -32,6 +32,14 @@ class UserFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = get_user_model() model = get_user_model()
@factory.post_generation
def groups(self, create, extracted, **kwargs):
if not create:
return
if extracted:
for group in extracted:
self.groups.add(group)
class AccountFactory(factory.django.DjangoModelFactory): class AccountFactory(factory.django.DjangoModelFactory):
b_day = Faker( b_day = Faker(
@ -42,7 +50,7 @@ class AccountFactory(factory.django.DjangoModelFactory):
city = Faker('city') city = Faker('city')
gender = factory.fuzzy.FuzzyChoice(range(1, 2)) gender = factory.fuzzy.FuzzyChoice(range(1, 2))
owner = factory.SubFactory(UserFactory) owner = factory.SubFactory(UserFactory)
photo = factory.django.ImageField(from_path=AVATAR_SAMPLE_IMAGE) photo = factory.django.ImageField(from_path=SAMPLE_IMAGE)
phone = Faker('phone_number') phone = Faker('phone_number')
class Meta: class Meta:

@ -0,0 +1,25 @@
ADMIN = 1
STUDENTS = 2
TEACHERS = 3
MANAGERS = 4
FINANCE_MANAGERS = 5
LEAD_MANAGERS = 6
CURATORS = 7
PARTNERS = 8
SUPPORTS = 9
FINANCE = 10
PROJECT_MANAGERS = 11
STATUS_CHOICES = (
(ADMIN, 'admin'),
(STUDENTS, 'students'),
(TEACHERS, 'teachers'),
(MANAGERS, 'managers'),
(FINANCE_MANAGERS, 'finance_managers'),
(LEAD_MANAGERS, 'lead_managers'),
(CURATORS, 'curators'),
(PARTNERS, 'partners'),
(SUPPORTS, 'supports'),
(FINANCE, 'finance'),
(PROJECT_MANAGERS, 'project_managers'),
)

@ -0,0 +1,56 @@
import os
import shutil
import pytest
from tests.client import BetterAPIClient
pytest_plugins = [
'access.tests.fixtures',
]
def pytest_sessionfinish(session, exitstatus):
""" whole test run finishes. """
print('pytest finish: cleanup')
if os.path.exists('media_qa'):
shutil.rmtree('media_qa')
@pytest.fixture
def api_client():
"""Anonymous client for REST API."""
client = BetterAPIClient()
return client
@pytest.fixture
def admin_client(admin):
"""Authorized as admin(superuser) client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=admin)
return client
@pytest.fixture
def student_client(student):
"""Authorized as student client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=student)
return client
@pytest.fixture
def manager_client(manager):
"""Authorized as manager client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=manager)
return client
@pytest.fixture
def lead_manager_client(lead_manager):
"""Authorized as lead manager client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=lead_manager)
return client

@ -0,0 +1,122 @@
import pytest
from access.factories import UserFactory, AccountFactory
from access import groups
@pytest.fixture
def admin():
"""
Create user as staff with data:
email = 'admin@example.com'
password = 'test'
is_staff = True
is_active = True
"""
user = UserFactory(
email='admin@example.com',
is_staff=True,
is_active=True,
groups__name=(groups.ADMIN,)
)
AccountFactory(owner=user)
return user
@pytest.fixture
def student():
"""
Create user as student with data:
email = 'student@example.com'
password = 'test'
is_active = True
in groups 'students'
"""
user = UserFactory.create(
email='student@example.com',
is_staff=False,
is_active=True,
groups__name=(groups.STUDENTS,)
)
AccountFactory(owner=user)
return user
@pytest.fixture
def student_not_active():
"""
Create user as student with data:
email = 'notactivestudent@example.com'
password = 'test'
is_active = False
in groups 'students'
"""
user = UserFactory.create(
email='notactivestudent@example.com',
is_staff=False,
is_active=False,
groups__name=(groups.STUDENTS,)
)
return user
@pytest.fixture
def manager():
"""
Create user as manager with data:
email = 'manager@example.com'
password = 'test'
is_staff = True
is_active = True
in groups 'managers'
"""
user = UserFactory.create(
email='manager@example.com',
is_staff=True,
is_active=True,
groups=(groups.MANAGERS,)
)
AccountFactory(owner=user)
return user
@pytest.fixture
def lead_manager():
"""
Create user as lead manager with data:
email = 'lead_manager@example.com'
password = 'test'
is_staff = True
is_active = True
in groups 'lead_managers'
"""
user = UserFactory.create(
email='lead_manager@example.com',
is_staff=True,
is_active=True,
groups=(groups.LEAD_MANAGERS,)
)
AccountFactory(owner=user)
return user
@pytest.fixture
def teacher():
"""
Create user as teacher with data:
email = 'teacher@example.com'
password = 'test'
is_staff = True
is_active = True
in groups 'teachers'
"""
user = UserFactory.create(
email='teacher@example.com',
is_staff=True,
is_active=True,
groups=(groups.TEACHERS,)
)
AccountFactory(owner=user)
return user

@ -0,0 +1,120 @@
import mock
import pytest
from django.contrib.auth import get_user_model
from django.urls import reverse
from rest_framework import status
from rest_framework.generics import get_object_or_404
from access.factories import USER_PASSWORD
@pytest.mark.django_db
@mock.patch('django.core.mail.EmailMessage.send')
def test_generate_password_by_manager(mocked_send_mail, manager_client,
student_client, student):
"""
Test generate new password from admin area by manager
"""
assert manager_client.get(
reverse('users:management-password'),
status=status.HTTP_405_METHOD_NOT_ALLOWED
)
assert student_client.get(
reverse('users:management-password'),
status=status.HTTP_403_FORBIDDEN
)
data = {
'email': student.email,
}
assert manager_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_201_CREATED
)
test_user = get_object_or_404(get_user_model(), email=student.email)
assert not test_user.check_password('test')
assert mocked_send_mail.call_count == 1
assert student_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_403_FORBIDDEN
)
wrong_data = {
'email': 'no_user@example.com',
}
assert manager_client.post(
reverse('users:management-password'),
data=wrong_data,
status=status.HTTP_404_NOT_FOUND
)
wrong_email = {
'email': 'no_user@example',
}
assert manager_client.post(
reverse('users:management-password'),
data=wrong_email,
status=status.HTTP_404_NOT_FOUND
)
@pytest.mark.django_db
def test_generate_password_by_manager_for_not_active_student(manager_client, student_not_active):
"""
Test generate new password from admin area by manager for not active student
"""
data = {
'email': student_not_active.email,
}
assert manager_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_201_CREATED
)
@pytest.mark.django_db
class TestLogin:
def test_login_user(self, api_client, student):
"""
Test login user
"""
data = {
'email': student.email,
'password': USER_PASSWORD
}
assert api_client.post(
reverse('users:login'),
data=data,
status=status.HTTP_200_OK
)
def test_login_user_wrong_password(self, api_client, student):
"""
Test login user with wrong password
"""
data = {
'email': student.email,
'password': USER_PASSWORD + '1'
}
assert api_client.post(
reverse('users:login'),
data=data,
status=status.HTTP_403_FORBIDDEN
)
def test_login_user_wrong_user(self, api_client, student):
"""
Test login user with wrong password
"""
data = {
'email': student.email + '1',
'password': USER_PASSWORD
}
assert api_client.post(
reverse('users:login'),
data=data,
status=status.HTTP_404_NOT_FOUND
)

@ -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 from rest_framework import permissions
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)
@ -296,7 +296,7 @@ class MinUserView(APIView):
return Response("User not found", status=404) return Response("User not found", status=404)
class ManagementPassword(generics.GenericAPIView): class ManagementPassword(APIView):
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser) permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
@staticmethod @staticmethod

@ -7,7 +7,7 @@ urlpatterns = [
url(r'courses/', include('courses.urls')), url(r'courses/', include('courses.urls')),
url(r'users/', include('access.urls', namespace='users')), url(r'users/', include('access.urls', namespace='users')),
url(r'library/', include('library.urls')), url(r'library/', include('library.urls')),
url(r'finance/', include('finance.urls')), url(r'finance/', include('finance.urls', namespace='finance')),
url(r'storage/', include('storage.urls')), url(r'storage/', include('storage.urls')),
url(r'progress/', include('progress.urls')), url(r'progress/', include('progress.urls')),
url(r'^docs/$', schema_view, name='api-docs'), url(r'^docs/$', schema_view, name='api-docs'),

@ -0,0 +1,62 @@
import uuid
import factory
import factory.fuzzy
from functools import partial
from access.factories import UserFactory
from access import groups
IMAGE_URL = 'https://dummyimage.com/240x240/000/fff.png'
BIG_IMAGE_URL = 'https://dummyimage.com/1200x800/000/fff.png'
BIG_MOBILE_IMAGE_URL = 'https://dummyimage.com/600x400/000/fff.png'
Faker = partial(factory.Faker, locale='ru_RU')
class CourseFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'courses.Course'
token = factory.LazyFunction(uuid.uuid4)
slug = factory.LazyAttribute(lambda x: factory.Faker('sentence').
generate({'nb_words': 3}).replace(' ', '-').replace('.', ''))
title = factory.LazyAttribute(lambda x: Faker('sentence').generate({'nb_words': 4}))
description = factory.LazyAttribute(
lambda x: '\n'.join(Faker('paragraphs').generate({'nb': 15}))
)
direction = factory.fuzzy.FuzzyChoice(range(1, 5))
public = True
image = IMAGE_URL
big_image = BIG_IMAGE_URL
big_mobile_image = BIG_MOBILE_IMAGE_URL
@factory.lazy_attribute
def teacher_tokens(self):
teacher = UserFactory(groups=(groups.TEACHERS,))
return [teacher.out_key]
class TopicFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'courses.Topic'
course = factory.SubFactory(CourseFactory)
title = factory.LazyAttribute(lambda x: Faker('sentence').generate({'nb_words': 4}))
description = factory.LazyAttribute(
lambda x: '\n'.join(Faker('paragraphs').generate({'nb': 15}))
)
sort = 0
class LessonFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'courses.Lesson'
token = factory.LazyFunction(uuid.uuid4)
key = factory.LazyFunction(uuid.uuid4)
topic = factory.SubFactory(TopicFactory)
title = factory.LazyAttribute(lambda x: Faker('sentence').generate({'nb_words': 4}))
sort = 0

@ -0,0 +1,18 @@
import pytest
from courses.factories import CourseFactory, LessonFactory, TopicFactory
@pytest.fixture
def course():
"""
Create course
"""
_course = CourseFactory()
topic = TopicFactory(
course=_course
)
LessonFactory(
topic=topic
)
return _course

@ -0,0 +1,72 @@
import uuid
import factory
import factory.fuzzy
from functools import partial
from django.utils import timezone
from yandex_money.models import Payment
from courses.factories import CourseFactory, TopicFactory, LessonFactory
from access.factories import UserFactory
from finance.models import Invoice
Faker = partial(factory.Faker, locale='ru_RU')
class BillFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'finance.Bill'
user = factory.SubFactory(UserFactory)
opener = factory.SubFactory(UserFactory)
description = Faker('text')
@factory.lazy_attribute
def course_token(self):
course = CourseFactory()
topic = TopicFactory(
course=course
)
LessonFactory(
topic=topic
)
return course.token
class InvoiceFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'finance.Invoice'
status = factory.fuzzy.FuzzyChoice(
(choice[0] for choice in Invoice.BILL_STATUSES)
)
price = factory.fuzzy.FuzzyDecimal(1000)
real_price = factory.fuzzy.FuzzyDecimal(1000)
method = factory.fuzzy.FuzzyChoice(
(choice[0] for choice in Invoice.BILL_METHOD)
)
key = factory.Faker('pyint')
yandex_pay = factory.SubFactory('factories.finance.PaymentFactory')
comment = Faker('word')
bill = factory.SubFactory(BillFactory)
class PaymentFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'yandex_money.Payment'
user = factory.SubFactory(UserFactory)
pub_date = timezone.now()
order_amount = factory.fuzzy.FuzzyDecimal(1000)
payment_type = factory.fuzzy.FuzzyChoice(
(choice[0] for choice in Payment.PAYMENT_TYPE.CHOICES)
)
order_number = factory.LazyFunction(uuid.uuid4)
status = factory.fuzzy.FuzzyChoice(
(choice[0] for choice in Payment.STATUS.CHOICES)
)
invoice_id = factory.Faker('pyint')
shop_amount = factory.fuzzy.FuzzyDecimal(1000)
performed_datetime = timezone.now()

@ -0,0 +1,58 @@
import os
import shutil
import pytest
from tests.client import BetterAPIClient
pytest_plugins = [
'access.tests.fixtures',
'finance.tests.fixtures',
'courses.tests.fixtures'
]
def pytest_sessionfinish(session, exitstatus):
""" whole test run finishes. """
print('pytest finish: cleanup')
if os.path.exists('media_qa'):
shutil.rmtree('media_qa')
@pytest.fixture
def api_client():
"""Anonymous client for REST API."""
client = BetterAPIClient()
return client
@pytest.fixture
def admin_client(admin):
"""Authorized as admin(superuser) client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=admin)
return client
@pytest.fixture
def student_client(student):
"""Authorized as student client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=student)
return client
@pytest.fixture
def manager_client(manager):
"""Authorized as manager client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=manager)
return client
@pytest.fixture
def lead_manager_client(lead_manager):
"""Authorized as lead manager client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=lead_manager)
return client

@ -0,0 +1,53 @@
import pytest
from yandex_money.models import Payment
from finance.factories import BillFactory, InvoiceFactory, PaymentFactory
PRICE = 1000.00
METHOD_CASH = 'C'
METHOD_YANDEX = 'Y'
STATUS_WAIT = 'W'
STATUS_ON_PAYMENT = 'P'
STATUS_PAID = 'F'
@pytest.fixture
def bill_cash(student, manager):
"""
Create bill for the student
"""
_bill = BillFactory(
user=student,
opener=manager,
)
InvoiceFactory(
status=STATUS_ON_PAYMENT,
method=METHOD_CASH,
yandex_pay=None,
bill=_bill
)
return _bill
@pytest.fixture
def bill_yandex(student, manager):
"""
Create bill for the student
"""
_bill = BillFactory(
user=student,
opener=manager,
)
# credit cart
payment = PaymentFactory(
user=student,
payment_type=Payment.PAYMENT_TYPE.AC,
status=Payment.STATUS.PROCESSED
)
InvoiceFactory(
status=STATUS_ON_PAYMENT,
method=METHOD_YANDEX,
yandex_pay=payment,
bill=_bill
)
return _bill

@ -0,0 +1,198 @@
import json
import mock
import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.response import Response
from yandex_money.models import Payment
from finance import models
from progress.models import Progress, ProgressLesson
from finance.tests.fixtures import PRICE, METHOD_CASH, STATUS_WAIT, STATUS_PAID
DUMMY_COMMENT = 'test comment'
DUMMY_DESCRIPTION = 'test description'
mock.patch('lms.global_decorators.transaction_decorator', lambda x: x).start()
@pytest.mark.django_db
def test_list_bills(api_client, student_client, student, manager, admin_client,
manager_client, lead_manager_client, bill_cash):
"""
Test for get list of bills
"""
assert api_client.get(
reverse('finance:bills'),
status=status.HTTP_403_FORBIDDEN
)
response = student_client.get(
reverse('finance:bills'),
status=status.HTTP_200_OK
)
results_student = json.loads(response.content)
assert len(results_student) is 1
assert results_student[0]['opener'] == manager.email
assert results_student[0]['user'] == student.email
response_admin = admin_client.get(
reverse('finance:bills'),
status=status.HTTP_200_OK
)
results_admin = json.loads(response_admin.content)
assert len(results_admin) is 0
response_manager = manager_client.get(
reverse('finance:bills'),
status=status.HTTP_200_OK
)
results_manager = json.loads(response_manager.content)
assert results_manager[0]['opener'] == manager.email
assert results_manager[0]['user'] == student.email
response_lead_manager = lead_manager_client.get(
reverse('finance:bills'),
status=status.HTTP_200_OK
)
results_lead_manager = json.loads(response_lead_manager.content)
assert len(results_lead_manager) is 0
@pytest.mark.django_db
def test_create_bill(api_client, student_client, manager_client,
manager, student, course):
"""
Test create bill
"""
data = {
'bill': {
'course_token': course.token.hex,
'opener': manager.email,
'user': student.email,
'comment': DUMMY_COMMENT,
'description': DUMMY_DESCRIPTION
},
'children': [{
'status': STATUS_WAIT,
'method': METHOD_CASH,
'price': PRICE,
'real_price': PRICE,
}]
}
response = manager_client.post(
reverse('finance:bills'),
data=data,
status=status.HTTP_200_OK
)
results = json.loads(response.content)
assert models.Bill.objects.get(user=student).id == results['bill']['id']
assert models.Invoice.objects.get(
bill=results['bill']['id']).id == results['children'][0]['id']
assert api_client.post(
reverse('finance:bills'),
data=data,
status=status.HTTP_403_FORBIDDEN
)
assert student_client.post(
reverse('finance:bills'),
data=data,
status=status.HTTP_403_FORBIDDEN
)
@pytest.mark.django_db
@mock.patch('django.core.mail.EmailMessage.send')
def test_confirm_pay_manager(mocked_email, manager_client, bill_cash, student):
assert Progress.objects.count() is 0
assert ProgressLesson.objects.count() is 0
data = {
'bill': {
'course_token': bill_cash.course_token.hex,
'opener': bill_cash.opener.email,
'user': bill_cash.user.email,
'comment': bill_cash.comment,
'description': bill_cash.description
},
'children': [{
'status': STATUS_PAID,
'method': METHOD_CASH,
'price': PRICE,
'real_price': PRICE,
}]
}
response = manager_client.post(
reverse('finance:bills'),
data=data,
status=status.HTTP_200_OK
)
results = json.loads(response.content)
assert models.Bill.objects.get(user=student).id == results['bill']['id']
assert Progress.objects.count() is 1
assert ProgressLesson.objects.count() is 1
progress = Progress.objects.filter(user=bill_cash.user).first()
assert Progress.objects.filter(user=bill_cash.user).exists() is True
assert ProgressLesson.objects.filter(progress=progress).exists() is True
assert mocked_email.call_count == 2
def fake_post_success(view, request):
pay = Payment.objects.get(order_number=request.data['orderNumber'])
pay.status = Payment.STATUS.SUCCESS
pay.save()
return Response('ok', status=status.HTTP_200_OK)
@pytest.mark.django_db
@mock.patch('django.core.mail.EmailMessage.send')
@mock.patch('finance.views.YandexCheckView.post', fake_post_success)
def test_confirm_pay_auto_success(mocked_email, api_client, bill_yandex, student):
assert Progress.objects.count() is 0
assert ProgressLesson.objects.count() is 0
invoice = bill_yandex.invoice_set.first()
payment = invoice.yandex_pay
data = {
'orderNumber': payment.order_number,
'shopSumAmount': str(payment.shop_amount)
}
api_client.post(
reverse('yandex_money_check'),
data=data,
status=status.HTTP_200_OK
)
assert Progress.objects.count() is 1
assert ProgressLesson.objects.count() is 1
progress = Progress.objects.filter(user=bill_yandex.user).first()
assert Progress.objects.filter(user=bill_yandex.user).exists() is True
assert ProgressLesson.objects.filter(progress=progress).exists() is True
assert mocked_email.call_count == 1
def fake_post_fail(view, request):
pay = Payment.objects.get(order_number=request.data['orderNumber'])
pay.status = Payment.STATUS.FAIL
pay.save()
return Response('fail', status=status.HTTP_200_OK)
@pytest.mark.django_db
@mock.patch('django.core.mail.EmailMessage.send')
@mock.patch('finance.views.YandexCheckView.post', fake_post_fail)
def test_confirm_pay_auto_fail(mocked_email, api_client, bill_yandex, student):
assert Progress.objects.count() is 0
assert ProgressLesson.objects.count() is 0
invoice = bill_yandex.invoice_set.first()
payment = invoice.yandex_pay
data = {
'orderNumber': payment.order_number,
'shopSumAmount': str(payment.shop_amount)
}
api_client.post(
reverse('yandex_money_check'),
data=data,
status=status.HTTP_200_OK
)
assert Progress.objects.count() is 0
assert ProgressLesson.objects.count() is 0
assert Progress.objects.filter(user=bill_yandex.user).exists() is False
assert mocked_email.call_count == 1

@ -3,7 +3,7 @@ from finance import views
urlpatterns = [ urlpatterns = [
url(r'payment/([0-9]{1,99})/$', views.YandexPay.as_view()), url(r'payment/([0-9]{1,99})/$', views.YandexPay.as_view()),
url(r'bills/$', views.BillListView.as_view()), url(r'bills/$', views.BillListView.as_view(), name='bills'),
url(r'bills/([0-9]{1,99})/$', views.BillDetailView.as_view()), url(r'bills/([0-9]{1,99})/$', views.BillDetailView.as_view()),
url(r'bills_find/$', views.FindBillView.as_view()), url(r'bills_find/$', views.FindBillView.as_view()),
url(r'yandex/fail/$', views.YandexFailView.as_view()), url(r'yandex/fail/$', views.YandexFailView.as_view()),

@ -380,4 +380,4 @@ class DemoYandexCheckView(YandexCheckView):
class DemoYandexAvisoView(YandexAvisoView): class DemoYandexAvisoView(YandexAvisoView):
pass pass

@ -8,7 +8,7 @@ import socket
root = environ.Path(__file__) - 2 root = environ.Path(__file__) - 2
env = environ.Env() env = environ.Env()
MOD = os.environ.get('MOD', 'Prod') MOD = os.environ.get('MOD', 'Test')
DEBUG = os.environ.get('DEBUG', 'False') DEBUG = os.environ.get('DEBUG', 'False')
MASTER_PASSWORD = os.environ.get('MASTER_PASSWORD', '@J*1') MASTER_PASSWORD = os.environ.get('MASTER_PASSWORD', '@J*1')

@ -0,0 +1,21 @@
import logging
from .settings import * # noqa
DEBUG = True
EMAIL_DEBUG = True
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG # noqa
MEDIA_ROOT = os.path.join(BASE_DIR, 'media_qa') # noqa
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
PASSWORD_HASHERS = ('django.contrib.auth.hashers.MD5PasswordHasher', )
CELERY_TASK_ALWAYS_EAGER = True
# Disable cache during testing
CACHE_DISABLED = True
LOGGING = {}
LOCAL_APPS_LOGGERS = {}
# Disable all logging calls with levels less severe than or equal to CRITICAL
logging.disable(logging.CRITICAL)

@ -1,5 +1,5 @@
[pytest] [pytest]
DJANGO_SETTINGS_MODULE = lms.settings DJANGO_SETTINGS_MODULE = lms.settings_qa
norecursedirs = env/* docs/* misc/* static/* norecursedirs = env/* docs/* misc/* static/*
;addopts = --flake8 -vvs ;addopts = --flake8 -vvs

@ -1,28 +0,0 @@
import pytest
from tests.client import BetterAPIClient
pytest_plugins = [
'tests.fixtures.users',
]
@pytest.fixture
def api_client():
"""Anonymous client for REST API."""
client = BetterAPIClient()
return client
@pytest.fixture
def staff_client(user_staff):
"""Authorized as staff client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=user_staff)
return client
@pytest.fixture
def student_client(user_student):
"""Authorized as staff client for REST API."""
client = BetterAPIClient()
client.force_authenticate(user=user_student)
return client

@ -1,63 +0,0 @@
import pytest
from factories.users import UserFactory, AccountFactory
@pytest.fixture
def user_staff():
"""
Create user as staff with data:
email = 'admin@example.com'
password = 'test'
is_staff=True
is_active = True
is_superuser = True
"""
admin = UserFactory(
last_name='Иванов',
first_name='Иван',
email='admin@example.com',
is_staff=True,
is_active=True,
is_superuser=True
)
AccountFactory(owner=admin)
return admin
@pytest.fixture
def user_student():
"""
Create user as student with data:
email = 'student@example.com'
password = 'test'
is_active = True
"""
student = UserFactory(
last_name='Иванов',
first_name='Иван',
email='student@example.com',
is_staff=False,
is_active=True,
)
AccountFactory(owner=student)
return student
@pytest.fixture
def user_not_active_student():
"""
Create user as student with data:
email = 'notactivestudent@example.com'
password = 'test'
is_active = False
"""
student = UserFactory(
last_name='Иванов',
first_name='Иван',
email='notactivestudent@example.com',
is_staff=False,
is_active=False,
)
return student

@ -1,124 +0,0 @@
import mock
import pytest
from django.contrib.auth import get_user_model
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')
def test_generate_password_by_manager(mocked_send_mail, staff_client,
student_client, user_student):
"""
Test generate new password from admin area by manager
"""
assert staff_client.get(
reverse('users:management-password'),
status=status.HTTP_405_METHOD_NOT_ALLOWED
)
assert student_client.get(
reverse('users:management-password'),
status=status.HTTP_403_FORBIDDEN
)
data = {
'email': user_student.email,
}
assert staff_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_201_CREATED
)
test_user = get_object_or_404(get_user_model(), email=user_student.email)
assert not test_user.check_password('test')
assert mocked_send_mail.call_count == 1
assert student_client.post(
reverse('users:management-password'),
data=data,
status=status.HTTP_403_FORBIDDEN
)
wrong_data = {
'email': 'no_user@example.com',
}
assert staff_client.post(
reverse('users:management-password'),
data=wrong_data,
status=status.HTTP_404_NOT_FOUND
)
wrong_email = {
'email': 'no_user@example',
}
assert staff_client.post(
reverse('users:management-password'),
data=wrong_email,
status=status.HTTP_404_NOT_FOUND
)
@pytest.mark.django_db
def test_generate_password_by_manager_for_not_active_student(staff_client,
user_not_active_student):
"""
Test generate new password from admin area by manager for not active student
"""
data = {
'email': user_not_active_student.email,
}
assert staff_client.post(
reverse('users:management-password'),
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
)
Loading…
Cancel
Save