remotes/origin/feature/test_courses
parent
3679d31293
commit
1ae3ac332d
20 changed files with 509 additions and 54 deletions
@ -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,62 @@ |
||||
import uuid |
||||
|
||||
import factory |
||||
import factory.fuzzy |
||||
|
||||
from functools import partial |
||||
|
||||
from factories.users 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,72 @@ |
||||
import uuid |
||||
|
||||
import factory |
||||
import factory.fuzzy |
||||
|
||||
from functools import partial |
||||
|
||||
from django.utils import timezone |
||||
from yandex_money.models import Payment |
||||
|
||||
from factories.courses import CourseFactory, TopicFactory, LessonFactory |
||||
from factories.users 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,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) |
||||
@ -0,0 +1,18 @@ |
||||
import pytest |
||||
|
||||
from factories.courses import CourseFactory, LessonFactory, TopicFactory |
||||
|
||||
|
||||
@pytest.fixture |
||||
def course(): |
||||
""" |
||||
Create course |
||||
""" |
||||
_course = CourseFactory() |
||||
topic = TopicFactory( |
||||
course=_course |
||||
) |
||||
LessonFactory( |
||||
topic=topic |
||||
) |
||||
return _course |
||||
@ -0,0 +1,21 @@ |
||||
import pytest |
||||
|
||||
from factories.finance import BillFactory, InvoiceFactory |
||||
|
||||
|
||||
@pytest.fixture |
||||
def bill_cash(student, manager): |
||||
""" |
||||
Create bill for the student |
||||
""" |
||||
_bill = BillFactory( |
||||
user=student, |
||||
opener=manager, |
||||
) |
||||
InvoiceFactory( |
||||
status='P', |
||||
method='C', |
||||
yandex_pay=None, |
||||
bill=_bill |
||||
) |
||||
return _bill |
||||
@ -0,0 +1,134 @@ |
||||
import json |
||||
|
||||
import mock |
||||
import pytest |
||||
|
||||
from django.urls import reverse |
||||
|
||||
from rest_framework import status |
||||
|
||||
from finance import models |
||||
from progress.models import Progress, ProgressLesson |
||||
|
||||
PRICE = 1000.00 |
||||
METHOD_CASH = 'C' |
||||
STATUS_WAIT = 'W' |
||||
STATUS_PAID = 'F' |
||||
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 |
||||
def test_confirm_pay_manager(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 |
||||
Loading…
Reference in new issue