From 57fc5c0070166781ac250a34e0a7839339f5fe95 Mon Sep 17 00:00:00 2001 From: Dmitriy Shesterkin Date: Wed, 28 Jun 2017 00:38:14 +0300 Subject: [PATCH] add deploy settings, test for task with message bonus --- .gitignore | 1 - conf/deploy/common.py | 4 ++ conf/deploy/stage.py | 4 ++ conf/deploy/stage.py.example | 7 ++++ requirements/base.txt | 12 ------ requirements/test.txt | 14 +++++++ src/customer/context_processors.py | 32 ++++++++++------ src/customer/utils.py | 60 +++++++++++++++++++++++++++++- src/factories/models.py | 34 ++++++++++++++++- src/tests/fixtures/models.py | 11 +++++- src/tests/test_tasks.py | 5 +++ src/tests/test_utils.py | 58 ++++++++++++++++++++++++++++- 12 files changed, 212 insertions(+), 30 deletions(-) create mode 100644 conf/deploy/common.py create mode 100644 conf/deploy/stage.py create mode 100644 conf/deploy/stage.py.example create mode 100644 requirements/test.txt diff --git a/.gitignore b/.gitignore index d9dc4c9..09f5125 100644 --- a/.gitignore +++ b/.gitignore @@ -198,4 +198,3 @@ target/ *.css.map ################################################################################ - diff --git a/conf/deploy/common.py b/conf/deploy/common.py new file mode 100644 index 0000000..7a4f9d3 --- /dev/null +++ b/conf/deploy/common.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +PROJECT_NAME = 'dokumentor' +REPO = 'git@bitbucket.org:Air51/dokumentor_dev.git' +BRANCH = 'develop' diff --git a/conf/deploy/stage.py b/conf/deploy/stage.py new file mode 100644 index 0000000..525ba05 --- /dev/null +++ b/conf/deploy/stage.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +USER = 'mitri4' +PASS = '9091324913Dasha' +HOSTS = ['mitri4.pro:8022'] diff --git a/conf/deploy/stage.py.example b/conf/deploy/stage.py.example new file mode 100644 index 0000000..8475f7e --- /dev/null +++ b/conf/deploy/stage.py.example @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +from deploy.common import * # noqa + +USER = 'username' +PASS = 'password' +HOSTS = ['domain_name:ssh_port'] + diff --git a/requirements/base.txt b/requirements/base.txt index 6e5f278..4859749 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -71,16 +71,4 @@ django-redis==4.8.0 redis==2.10.5 trans==2.1.0 python-decouple==3.0 -flake8==3.3.0 numpy==1.13.0 -mock==2.0.0 -mockredispy==2.9.3 -pytest-django==3.1.2 -pytest-sugar==0.8.0 -factory-boy==2.8.1 -django-test-plus==1.0.17 -Faker==0.7.15 -coverage==4.4.1 -pytest-flake8==0.8.1 -pycodestyle==2.3.1 -pyflakes==1.5.0 diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 0000000..0247a4d --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,14 @@ +-r base.txt +freezegun-0.3.9 +mock==2.0.0 +mockredispy==2.9.3 +pytest-django==3.1.2 +pytest-sugar==0.8.0 +factory-boy==2.8.1 +django-test-plus==1.0.17 +Faker==0.7.15 +coverage==4.4.1 +pytest-flake8==0.8.1 +pycodestyle==2.3.1 +pyflakes==1.5.0 +flake8==3.3.0 diff --git a/src/customer/context_processors.py b/src/customer/context_processors.py index 3571e54..d0f2a13 100644 --- a/src/customer/context_processors.py +++ b/src/customer/context_processors.py @@ -3,6 +3,7 @@ import logging from datetime import datetime, timedelta from django.core.cache import cache from customer.models import License +from customer.utils import get_display_message_for_bonus log = logging.getLogger(__name__) @@ -14,11 +15,6 @@ def license_check_soon_ends(request): days_left = cache.get(f'days_left_{request.user.username}', None) cur_license = cache.get(f'cur_license_{request.user.username}', None) - print(license_cookie) - print(license_15days) - print(days_left) - print(cur_license) - if not days_left or not cur_license: now = datetime.today() cur_license = License.objects.filter( @@ -66,10 +62,22 @@ def license_check_soon_ends(request): def confirm_user_bonus(request): if request.user: - bonus_url = '#' - message = f'У вас есть ещё 10 дней, чтобы получить бонус' - test_message = 'This message is personal confirm for current user' - return { - 'confirm_bonus': True, - 'message_bonus': message - } + context = {} + close_bonus_cookie = request.COOKIES.get('close_message_bonus') + confirm_bonus_days = cache.get(f'confirm_bonus_days_{request.user.username}', None) + + if confirm_bonus_days >= 0: + message = get_display_message_for_bonus(confirm_bonus_days) + context['confirm_bonus'] = True + context['message'] = message + return context + + if not close_bonus_cookie: + pass + else: + return context + + # return { + # 'confirm_bonus': True, + # 'message_bonus': message + # } diff --git a/src/customer/utils.py b/src/customer/utils.py index 38df52a..af8a59b 100644 --- a/src/customer/utils.py +++ b/src/customer/utils.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from datetime import timedelta +from pytils import numeral +from django.utils import timezone from django.conf import settings from django.core.mail import EmailMessage from django.template.loader import render_to_string @@ -9,11 +11,10 @@ from commons.utils import get_site_url def check_one_profile(profile, now, manual=False): - from customer.models import License profile_is_active = profile.active - licenses = License.objects.\ + licenses = License.objects. \ filter(company=profile, date_from__lte=now, date_to__gte=now, status__in=[-1, 1, 2], deleted=False) licenses.filter(status=1).update(status=2) @@ -98,3 +99,58 @@ def raise_if_no_profile(request): raise Exception( f"Profile not found for user: {request.user.pk}, '{request.user.username}'" ) + + +def check_confirm_bonus_to_user(user): + """ + Check user for displaying a message with an offer for + purchase of licenses for additional bonus licenses + Show message only for new users in the period + from 5 to 15 day + If user already have licenses don't display message + :param user: DockUser instance + :return: count of days remaining for getting bonus, + integer or False if nothing to use + """ + from customer.models import License + + lic = License.objects.filter( + company=user.profile, + status__in=[1, 2], + deleted=False + ) + if lic: + return False + + today = timezone.now().date() + date_join_start = today - timezone.timedelta(days=15) + date_join_end = today - timezone.timedelta(days=6) + if date_join_start <= user.date_joined.date() <= date_join_end: + delta = user.date_joined.date() - date_join_start + return delta.days + + return False + + +def get_display_message_for_bonus(day_count): + """ + Get text to display the message depending on count of days + :param day_count: Count of days, integer + :return: Message for display in page, string + """ + message = '' + + if type(day_count) == str: + return message + + if day_count > 10: + return message + + if day_count == 0: + message = f'Сегодня последний день что бы получить бонус' + if day_count > 0: + message = f'У вас есть ещё {day_count} ' \ + f'{numeral.choose_plural(day_count, "день, дня, дней")}, ' \ + f'чтобы получить бонус' + + return message diff --git a/src/factories/models.py b/src/factories/models.py index 65cf958..780e627 100755 --- a/src/factories/models.py +++ b/src/factories/models.py @@ -6,7 +6,7 @@ import factory.fuzzy from django.contrib.auth import get_user_model from myauth.models import ConfirmEmail -from customer.models import UserProfile +from customer.models import UserProfile, License from functools import partial USER_PASSWORD = 'test' @@ -74,3 +74,35 @@ class ConfirmEmailFactory(factory.django.DjangoModelFactory): class Meta: model = ConfirmEmail + + +class LicenseFactory(factory.django.DjangoModelFactory): + company = factory.SubFactory(ProfileFactory) + term = factory.Iterator([1, 6, 12, 24]) + date_from = Faker( + 'past_datetime', + start_date='-30d', + tzinfo=pytz.UTC + ) + date_to = Faker( + 'future_datetime', + end_date='+30d', + tzinfo=pytz.UTC + ) + payform = factory.Iterator([0, 1]) + status = factory.Iterator([1, 2]) + order_date = Faker( + 'past_datetime', + start_date='-30d', + tzinfo=pytz.UTC + ) + paid_date = Faker( + 'past_datetime', + start_date='-30d', + tzinfo=pytz.UTC + ) + pay_sum = factory.Iterator([1000, 2000]) + deleted = False + + class Meta: + model = License diff --git a/src/tests/fixtures/models.py b/src/tests/fixtures/models.py index 0bc2e7d..7f88d35 100644 --- a/src/tests/fixtures/models.py +++ b/src/tests/fixtures/models.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- import pytest -from factories.models import UserFactory, ConfirmEmailFactory +from factories.models import UserFactory, ConfirmEmailFactory, LicenseFactory @pytest.fixture @@ -17,3 +17,12 @@ def confirm_email(): def profile(): _user = UserFactory() return _user.profile + + +@pytest.fixture() +def lic(): + _user = UserFactory() + _lic = LicenseFactory() + _lic.company = _user.profile + _lic.save() + return _lic diff --git a/src/tests/test_tasks.py b/src/tests/test_tasks.py index 0ea226b..6fb5417 100644 --- a/src/tests/test_tasks.py +++ b/src/tests/test_tasks.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- import pytest +from freezegun import freeze_time + from django.utils import timezone + from myauth.models import DokUser, ConfirmEmail from customer.models import UserProfile @@ -23,6 +26,7 @@ dates_lt_five = [timezone.now() - timezone.timedelta(days=5), dates_bonus = [timezone.now() - timezone.timedelta(days=5)] +@freeze_time("2017-06-28 00:21:34", tz_offset=2) @pytest.mark.parametrize('create_date', dates_gte_five) @pytest.mark.django_db def test_delete_not_activated_users_great_five_days(user, create_date): @@ -61,6 +65,7 @@ def test_delete_not_activated_users_less_five_day(user, create_date): assert ConfirmEmail.objects.count() == 1 +@freeze_time("2017-06-28 00:21:34", tz_offset=2) @pytest.mark.parametrize('create_date', dates_bonus) @pytest.mark.django_db def test_send_offer_for_get_bonus(user, create_date): diff --git a/src/tests/test_utils.py b/src/tests/test_utils.py index 35be02c..d3a651b 100644 --- a/src/tests/test_utils.py +++ b/src/tests/test_utils.py @@ -4,7 +4,19 @@ import pytest from django.utils import timezone from commons.utils import get_site_url -from customer.utils import check_one_profile +from customer.utils import check_one_profile, check_confirm_bonus_to_user +from customer.utils import get_display_message_for_bonus + + +dates = [timezone.now() - timezone.timedelta(days=6), + timezone.now() - timezone.timedelta(days=10), + timezone.now() - timezone.timedelta(days=15)] + +dates_not_in_range = [timezone.now() - timezone.timedelta(days=5), + timezone.now() - timezone.timedelta(days=16)] + +days = [1, 5, 10, 4, 6, 0] +not_days = ['1', 11, 'test'] def test_utils_with_request(mocked_request): @@ -17,6 +29,50 @@ def test_utils_without_request(): assert len(url.split('//')) == 2 +@pytest.mark.parametrize('create_date', dates) +@pytest.mark.django_db +def test_check_confirm_bonus_to_user(user, create_date): + user.date_joined = create_date + user.save() + day_remain = check_confirm_bonus_to_user(user) + assert day_remain >= 0 + + +@pytest.mark.parametrize('create_date', dates_not_in_range) +@pytest.mark.django_db +def test_check_confirm_bonus_to_user_not_in_range(user, create_date): + user.date_joined = create_date + user.save() + day_remain = check_confirm_bonus_to_user(user) + assert day_remain is False + + +@pytest.mark.parametrize('create_date', dates) +@pytest.mark.django_db +def test_check_confirm_bonus_to_user_with_license(lic, create_date): + user = lic.company.users.first() + user.date_joined = create_date + user.save() + day_remain = check_confirm_bonus_to_user(user) + assert day_remain is False + + +@pytest.mark.parametrize('count_day', days) +def test_get_display_message_for_bonus(count_day): + text = get_display_message_for_bonus(count_day) + assert text != '' + if count_day == 0: + assert 'последний' in text + if count_day != 0: + assert 'последний' not in text + + +@pytest.mark.parametrize('count_day', not_days) +def test_get_display_message_for_bonus_not_valid(count_day): + text = get_display_message_for_bonus(count_day) + assert text == '' + + @pytest.mark.django_db def test_check_one_profile(profile): check_one_profile(profile, timezone.now(), manual=False)