refactor project, add task delete not activated users

prod
Dmitriy Shesterkin 9 years ago
parent 5395a56480
commit 8656fc7903
  1. 34
      Makefile
  2. 17
      README.md
  3. 6
      conf/docker/entrypoint.sh
  4. 9
      conf/docker/entrypoint_stage.sh
  5. 2
      conf/env.local
  6. 2
      conf/env.stage
  7. 2
      conf/env.template
  8. 10
      conf/supervisor.conf
  9. 4
      manage.py
  10. 19
      pytest.ini
  11. 9
      requirements/base.txt
  12. 7
      src/customer/tasks.py
  13. 1
      src/dokumentor/settings/__init__.py
  14. 2
      src/dokumentor/settings/local.py
  15. 2
      src/dokumentor/settings/production.py
  16. 2
      src/dokumentor/settings/stage.py
  17. 26
      src/dokumentor/settings/testing.py
  18. 0
      src/factories/__init__.py
  19. 76
      src/factories/models.py
  20. 4
      src/tests/conftest.py
  21. 13
      src/tests/fixtures/models.py
  22. 61
      src/tests/test_tasks.py
  23. 4
      tox.ini

@ -1,4 +1,4 @@
.PHONY: all help build virtualenv requirements-local loaddata run migrate shell collectstatic clean worker
.PHONY: all help build virtualenv requirements-local loaddata run migrate shell collectstatic clean worker qa
# target: all - Default target. Does nothing.
all:
@ -25,31 +25,31 @@ requirements-local:
# target: loaddata - Load fixtures
loaddata:
python src/manage.py loaddata src/myauth/fixtures/myauth.json
python src/manage.py loaddata src/commons/fixtures/cms.json
python src/manage.py loaddata src/commons/fixtures/djangocms_text_ckeditor.json
python src/manage.py loaddata src/commons/fixtures/sites.json
python src/manage.py loaddata src/customer/fixtures/price.json
python src/manage.py loaddata src/docs/fixtures/country.json
python src/manage.py loaddata src/docs/fixtures/currency.json
python src/manage.py loaddata src/docs/fixtures/measure.json
python manage.py loaddata src/myauth/fixtures/myauth.json
python manage.py loaddata src/commons/fixtures/cms.json
python manage.py loaddata src/commons/fixtures/djangocms_text_ckeditor.json
python manage.py loaddata src/commons/fixtures/sites.json
python manage.py loaddata src/customer/fixtures/price.json
python manage.py loaddata src/docs/fixtures/country.json
python manage.py loaddata src/docs/fixtures/currency.json
python manage.py loaddata src/docs/fixtures/measure.json
# target: run - Runserver
run:
python src/manage.py runserver 0.0.0.0:8000
python manage.py runserver 0.0.0.0:8000
# target: migrate - Build all docker containers, defined in docker-compose.stage.yml
migrate:
python src/manage.py migrate myauth --noinput
python src/manage.py migrate --noinput
python manage.py migrate myauth --noinput
python manage.py migrate --noinput
# target: shell - Run python shell
shell:
python src/manage.py shell
python manage.py shell
# target: collectstatic - Run collectstatic
collectstatic:
python src/manage.py collectstatic --noinput
python manage.py collectstatic --noinput
clean_temp:
@ -68,4 +68,8 @@ clean: clean_temp clean_venv clean_db
# target: worker - Run celery worker
worker:
cd src && celery -A dokumentor worker -l info -E -B
celery -A src.dokumentor worker -l info -E -B
# target: qa - Run pytest
qa:
pytest

@ -24,7 +24,7 @@ git checkout develop
```bash
virtualenv --python=python3 env
source env/bin/activate
pip install -r requirements.txt
pip install -r requirements/local.txt
```
### Настройка окружения
@ -36,23 +36,26 @@ cp conf/env.template conf/env
Накатываем миграции и заполняем базу данных
```bash
bin/migrate.sh
make migrate
```
Загружаем фикстуры
```bash
bin/loaddata.sh
make loaddata
```
### Установка проекта для разработки командой `make`
### Установка проекта для разработки
Для разработки проект можно развернуть выполив
```bash
make
make run
```
###Запуск сервера Celery
```bash
cd src
celery -A dokumentor worker -l info -E
make worker
```
###Запуск Тестов
```bash
make qa
```

@ -2,12 +2,12 @@
# Make database migrations
echo "Make database migrations"
python src/manage.py migrate makemigrations
python manage.py migrate makemigrations
# Apply database migrations
echo "Apply database migrations"
python src/manage.py migrate myauth --noinput
python src/manage.py migrate --noinput
python manage.py migrate myauth --noinput
python manage.py migrate --noinput
cd /opt/app

@ -11,16 +11,15 @@ bower install --allow-root
# Collect static files
echo "Collect static files"
python src/manage.py collectstatic --noinput
python manage.py collectstatic --noinput
# Make database migrations
echo "Make database migrations"
python src/manage.py makemigrations
python manage.py makemigrations
# Apply database migrations
echo "Apply database migrations"
python src/manage.py migrate myauth --noinput
python src/manage.py migrate --noinput
python manage.py migrate myauth --noinput
python manage.py migrate --noinput
supervisord -c /opt/app/conf/supervisor.conf

@ -1,4 +1,4 @@
DJANGO_SETTINGS_MODULE='dokumentor.settings.local'
DJANGO_SETTINGS_MODULE='src.dokumentor.settings.local'
DJANGO_SECRET='CHANGE_ME_IN_PRODUCTION'

@ -1,4 +1,4 @@
DJANGO_SETTINGS_MODULE=dokumentor.settings.stage
DJANGO_SETTINGS_MODULE=src.dokumentor.settings.stage
SSL=False

@ -1,4 +1,4 @@
DJANGO_SETTINGS_MODULE=dokumentor.settings.{{env}}
DJANGO_SETTINGS_MODULE=src.dokumentor.settings.{{env}}
DJANGO_SECRET='CHANGE_ME_IN_PRODUCTION'

@ -17,8 +17,8 @@ stdout_events_enabled=true
stderr_events_enabled=true
[program:gunicorn]
command=gunicorn dokumentor.wsgi:application -c /opt/app/conf/gunicorn_prod.py
directory=/opt/app/src
command=gunicorn src.dokumentor.wsgi:application -c /opt/app/conf/gunicorn_prod.py
directory=/opt/app
priority=2
stdout_logfile=/var/log/gunicorn.log
redirect_stderr=true
@ -27,10 +27,10 @@ stderr_events_enabled=true
autorestart=true
[program:celeryd]
command=celery -A dokumentor worker -l info -E -B
directory=/opt/app/src
command=celery -A src.dokumentor worker -l info -E -B
directory=/opt/app
stdout_logfile=/var/log/celery-worker.log
stderr_logfile=/var/log/celery-worker.log
stderr_logfile=/var/log/celery-worker-error.log
autostart=true
autorestart=true
startsecs=10

@ -6,9 +6,11 @@ import sys
import envvars as env
if __name__ == "__main__":
env_file = p.normpath(p.join(p.abspath(p.dirname(__file__)), "../conf/env"))
env_file = p.normpath(p.join(p.abspath(p.dirname(__file__)), "./conf/env"))
env.load(env_file)
print(env_file)
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

@ -0,0 +1,19 @@
[pytest]
DJANGO_SETTINGS_MODULE = src.dokumentor.settings.testing
norecursedirs = env/* docs/* misc/* static/* mysql/*
addopts = --flake8 -vv -s
python_files =
test_*.py
flake8-max-line-length = 99
# E731 - do not assign a lambda expression, use a def
# F405 - name may be undefined, or defined from star imports: module
flake8-ignore =
*.py E731 F405
**/conf/** ALL
**/migrations/** ALL
**/templates/** ALL

@ -73,3 +73,12 @@ trans==2.1.0
python-decouple==3.0
flake8==3.2.1
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

@ -3,11 +3,11 @@ from __future__ import absolute_import
import traceback
from django.utils import timezone
from datetime import datetime, timedelta
from celery import shared_task
from django.utils import timezone
from django.core.mail import mail_admins
from myauth.models import DokUser, ConfirmEmail
@ -43,13 +43,12 @@ def check_license():
@shared_task
def delete_not_activated_users():
now = timezone.now()
users = DokUser.objects.filter(profile__active=False, profile__confirmed=False).\
filter(profile__created_at__lte=now - timedelta(5))
filter(profile__created_at__lte=timezone.now() - timezone.timedelta(days=5))
if users:
for user in users:
profile = user.profile
confirm = ConfirmEmail.objects.filter(user=user, is_confirmed=False)
confirm = ConfirmEmail.objects.filter(user=user, is_confirmed=False).first()
if profile:
profile.delete()
if confirm:

@ -1 +0,0 @@
# -*- coding: utf-8 -*-

@ -2,7 +2,7 @@
import dj_database_url
from dokumentor.settings.common import *
from src.dokumentor.settings.common import * # noqa
def custom_show_toolbar(self):

@ -2,7 +2,7 @@
import dj_database_url
from dokumentor.settings.common import *
from src.dokumentor.settings.common import * # noqa
DEBUG = False
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG

@ -2,7 +2,7 @@
import dj_database_url
from dokumentor.settings.common import *
from src.dokumentor.settings.common import * # noqa
DEBUG = False
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
import logging
import dj_database_url
from src.dokumentor.settings.common import * # noqa
DEBUG = True
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG # noqa
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
PASSWORD_HASHERS = ('django.contrib.auth.hashers.MD5PasswordHasher', )
DATABASES = {
'default': dj_database_url.parse(e.get('TEST_DB')),
}
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,76 @@
import pytz
import factory
import factory.fuzzy
from django.contrib.auth import get_user_model
from myauth.models import ConfirmEmail
from customer.models import UserProfile
from functools import partial
USER_PASSWORD = 'test'
Faker = partial(factory.Faker, locale='ru_RU')
class ProfileFactory(factory.django.DjangoModelFactory):
profile_type = factory.Iterator([1, 2])
boss_surname = Faker('last_name')
boss_name = Faker('first_name')
boss_midname = Faker('middle_name')
inn = factory.Faker('isbn10')
ogrn = factory.Faker('isbn10')
okpo = factory.Faker('isbn10')
glavbuh_surname = Faker('last_name')
glavbuh_name = Faker('first_name')
glavbuh_midname = Faker('middle_name')
address = Faker('address')
jur_address = Faker('address')
real_address = Faker('address')
phone = Faker('phone_number')
fax = Faker('phone_number')
email = Faker('email')
site = Faker('url')
svid_gos_reg = factory.Faker('isbn10')
ip_reg_date = factory.Faker('date')
name = Faker('company')
full_name = f'{Faker("company_prefix")} {Faker("company")}'
kpp = factory.Faker('ean8')
boss_title = Faker('job')
na_osnovanii = factory.fuzzy.FuzzyChoice(['устава', 'положения'])
active = True
confirmed = True
user_session_key = Faker('sha1')
class Meta:
model = UserProfile
class UserFactory(factory.django.DjangoModelFactory):
first_name = Faker('first_name')
last_name = Faker('last_name')
username = Faker('user_name')
email = Faker('email')
password = factory.PostGenerationMethodCall('set_password', USER_PASSWORD)
is_active = True
is_staff = False
date_joined = Faker(
'past_datetime',
start_date='-30d',
tzinfo=pytz.UTC
)
profile = factory.SubFactory(ProfileFactory)
class Meta:
model = get_user_model()
django_get_or_create = ('username',)
class ConfirmEmailFactory(factory.django.DjangoModelFactory):
user = factory.SubFactory(UserFactory)
is_confirmed = True
class Meta:
model = ConfirmEmail

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
pytest_plugins = [
'src.tests.fixtures.models'
]

@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
import pytest
from factories.models import UserFactory, ConfirmEmail
@pytest.fixture
def user():
return UserFactory()
@pytest.fixture
def confirm_email():
return ConfirmEmail()

@ -0,0 +1,61 @@
# -*- coding: utf-8 -*-
import pytest
from django.utils import timezone
from myauth.models import DokUser, ConfirmEmail
from customer.models import UserProfile
from customer.tasks import delete_not_activated_users
@pytest.mark.django_db
def test_delete_not_activated_users_more_than_five_day(user):
user.is_active = False
profile = user.profile
profile.active = False
profile.confirmed = False
profile.created_at = timezone.now() - timezone.timedelta(days=15)
profile.save()
user.save()
ConfirmEmail.objects.get_or_create(user=user)
delete_not_activated_users()
assert DokUser.objects.count() == 0
assert UserProfile.objects.count() == 0
assert ConfirmEmail.objects.count() == 0
@pytest.mark.django_db
def test_delete_not_activated_users_equal_five_day(user):
user.is_active = False
profile = user.profile
profile.active = False
profile.confirmed = False
profile.created_at = timezone.now() - timezone.timedelta(days=5)
profile.save()
user.save()
ConfirmEmail.objects.get_or_create(user=user)
delete_not_activated_users()
assert DokUser.objects.count() == 0
assert UserProfile.objects.count() == 0
assert ConfirmEmail.objects.count() == 0
@pytest.mark.django_db
def test_delete_not_activated_users_less_five_day(user):
user.is_active = False
profile = user.profile
profile.active = False
profile.confirmed = False
profile.created_at = timezone.now() - timezone.timedelta(days=4)
profile.save()
user.save()
ConfirmEmail.objects.get_or_create(user=user)
delete_not_activated_users()
assert DokUser.objects.count() == 1
assert UserProfile.objects.count() == 1
assert ConfirmEmail.objects.count() == 1

@ -1,4 +0,0 @@
[flake8]
ignore = F403
max-line-length = 120
exclude = ./venv/*,*/migrations/*, ./node_modules/*
Loading…
Cancel
Save