diff --git a/artel/artel/settings/test.py b/artel/artel/settings/test.py new file mode 100644 index 0000000..245415e --- /dev/null +++ b/artel/artel/settings/test.py @@ -0,0 +1,12 @@ +from artel.settings.base import * + +# SECURITY WARNING: define the correct hosts in production! +ALLOWED_HOSTS = ["*"] + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = "smtp-server" +EMAIL_HOST_USER = None +EMAIL_HOST_PASSWORD = None +EMAIL_PORT = 1025 +EMAIL_USE_TLS = False +DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL', 'mtyton@tepewu.pl') diff --git a/artel/artel/settings/tests.py b/artel/artel/settings/tests.py index 41c6b42..2d21aa6 100644 --- a/artel/artel/settings/tests.py +++ b/artel/artel/settings/tests.py @@ -3,6 +3,8 @@ from .base import * # SECURITY WARNING: define the correct hosts in production! ALLOWED_HOSTS = ["*"] +SECRET_KEY = "test" + EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = "smtp-server" EMAIL_HOST_USER = None diff --git a/artel/artel/tasks.py b/artel/artel/tasks.py index 3233132..958d8de 100644 --- a/artel/artel/tasks.py +++ b/artel/artel/tasks.py @@ -1,12 +1,13 @@ -from celery import shared_task -from easy_thumbnails.files import generate_all_aliases +import celery import logging +from easy_thumbnails.files import generate_all_aliases + logger = logging.getLogger(__name__) -@shared_task(serializer="pickle") +@celery.shared_task(name="generate_thumbnails") def generate_thumbnails(model, pk, field): try: instance = model._default_manager.get(pk=pk) diff --git a/artel/docker-compose-test.yml b/artel/docker-compose-test.yml index d3a32f5..2ec266a 100644 --- a/artel/docker-compose-test.yml +++ b/artel/docker-compose-test.yml @@ -8,6 +8,14 @@ services: - POSTGRES_USER=comfy - POSTGRES_PASSWORD=password - POSTGRES_DB=comfy_shop + + test_rabbit: + hostname: rabbit + image: rabbitmq:3.6.0 + environment: + - RABBITMQ_DEFAULT_USER=rabbitmq + - RABBITMQ_DEFAULT_PASS=rabbitmq + test_comfy: depends_on: - test_db @@ -19,5 +27,34 @@ services: - SECRET_KEY=RandomKey - DATABASE_URL=postgres://comfy:password@test_db/comfy_shop - DJANGO_SETTINGS_MODULE=artel.settings.tests + - RABBITMQ_DEFAULT_USER=rabbitmq + - RABBITMQ_DEFAULT_PASS=rabbitmq command: python manage.py test --noinput + + test_beat: + build: + context: . + dockerfile: Dockerfile + command: celery -A artel beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler + environment: + - SECRET_KEY=RandomKey + - DATABASE_URL=postgres://comfy:password@test_db/comfy_shop + - DJANGO_SETTINGS_MODULE=artel.settings.tests + depends_on: + - test_comfy + - test_rabbit + + test_worker: + build: + context: . + dockerfile: Dockerfile + command: celery -A artel worker -l info + environment: + - SECRET_KEY=RandomKey + - DATABASE_URL=postgres://comfy:password@test_db/comfy_shop + - DJANGO_SETTINGS_MODULE=artel.settings.tests + depends_on: + - test_comfy + - test_rabbit + - test_beat \ No newline at end of file diff --git a/artel/docker-compose.yml b/artel/docker-compose.yml index c4ac620..cdd0927 100644 --- a/artel/docker-compose.yml +++ b/artel/docker-compose.yml @@ -75,7 +75,7 @@ services: command: celery -A artel worker -l info volumes: - ./:/app - - media:/app/media + - ./media:/app/media env_file: - .env environment: diff --git a/artel/store/apps.py b/artel/store/apps.py index 5db39b5..41658c1 100644 --- a/artel/store/apps.py +++ b/artel/store/apps.py @@ -4,4 +4,3 @@ from django.apps import AppConfig class StoreConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'store' - diff --git a/artel/store/migrations/0014_alter_productimage_image_and_more.py b/artel/store/migrations/0014_alter_productimage_image_and_more.py index c4ed3ed..909a194 100644 --- a/artel/store/migrations/0014_alter_productimage_image_and_more.py +++ b/artel/store/migrations/0014_alter_productimage_image_and_more.py @@ -21,4 +21,3 @@ class Migration(migrations.Migration): field=easy_thumbnails.fields.ThumbnailerImageField(upload_to=""), ) ] - \ No newline at end of file diff --git a/artel/store/models.py b/artel/store/models.py index 0fa495b..0d0fd16 100644 --- a/artel/store/models.py +++ b/artel/store/models.py @@ -23,6 +23,7 @@ from django.template import ( from django.core.exceptions import ValidationError from django.db.models.signals import m2m_changed from django.forms import CheckboxSelectMultiple +from django.dispatch import receiver from modelcluster.models import ClusterableModel from modelcluster.fields import ParentalKey @@ -35,17 +36,14 @@ from wagtail import fields as wagtail_fields from taggit.managers import TaggableManager from phonenumber_field.modelfields import PhoneNumberField from num2words import num2words +from easy_thumbnails.fields import ThumbnailerImageField +from easy_thumbnails.signals import saved_file from mailings.models import ( OutgoingEmail, Attachment ) - -from easy_thumbnails.fields import ThumbnailerImageField - -from django.dispatch import receiver -from easy_thumbnails.signals import saved_file -from artel import tasks +from artel.tasks import generate_thumbnails logger = logging.getLogger(__name__) @@ -542,6 +540,7 @@ class OrderDocument(models.Model): @receiver(saved_file) def generate_thumbnails_async(sender, fieldfile, **kwargs): - tasks.generate_thumbnails.delay( + generate_thumbnails.delay( model=sender, pk=fieldfile.instance.pk, - field=fieldfile.field.name) + field=fieldfile.field.name + ) diff --git a/artel/store/tasks.py b/artel/store/tasks.py index cebc7f4..35bb51f 100644 --- a/artel/store/tasks.py +++ b/artel/store/tasks.py @@ -1,5 +1,7 @@ import logging +import celery from django.conf import settings +from easy_thumbnails.files import generate_all_aliases from mailings.models import OutgoingEmail from store.models import Product @@ -8,8 +10,8 @@ from store.admin import ProductAdmin logger = logging.getLogger(__name__) -# TODO - those should be modified to be celery tasks +@celery.shared_task(name="send_produt_request_email") def send_produt_request_email(variant_pk: int): try: variant = Product.objects.get(pk=variant_pk) diff --git a/artel/store/tests/test_celery.py b/artel/store/tests/test_celery.py deleted file mode 100644 index fb1d581..0000000 --- a/artel/store/tests/test_celery.py +++ /dev/null @@ -1,34 +0,0 @@ -from django.test import TestCase -from store.tests.factories import ProductTemplateFactory -from store.models import ProductTemplateImage -from django.core.files.uploadedfile import SimpleUploadedFile -from artel.tasks import generate_thumbnails -from abc import ABC - - -class AbstractThumbnailGenerationTest(TestCase, ABC): - model_factory = None - - def test_generate_thumbnails(self): - model_instance = self.model_factory() - image_path = "media/dow.jpg" - image_file = SimpleUploadedFile("test_image.jpg", - open(image_path, "rb").read(), - content_type="image/jpeg") - instance_mock = self.model_class( - template=model_instance, - image=image_file, - is_main=True - ) - instance_mock.save() - instance_pk = instance_mock.pk - - result = generate_thumbnails(model=instance_mock.__class__, - pk=instance_pk, - field="image") - self.assertTrue(result["status"]) - - -class ProductTemplateImageThumbnailTest(AbstractThumbnailGenerationTest): - model_factory = ProductTemplateFactory - model_class = ProductTemplateImage diff --git a/artel/store/tests/test_signals.py b/artel/store/tests/test_signals.py deleted file mode 100644 index 5e115de..0000000 --- a/artel/store/tests/test_signals.py +++ /dev/null @@ -1,33 +0,0 @@ -from django.test import TestCase -from django.core.files.uploadedfile import SimpleUploadedFile -from unittest.mock import patch -from store.tests.factories import ProductTemplateFactory -from store.models import ProductTemplateImage -from abc import ABC - - -class AbstractSignalTest(TestCase, ABC): - def setUp(self): - self.template_instance = ProductTemplateFactory() - - def create_instance_mock(self): - raise NotImplementedError("Subclasses must implement this method") - - @patch("artel.tasks.generate_thumbnails.delay") - def test_generate_thumbnails_async_signal(self, mock_generate_thumbnails): - self.instance_mock = self.create_instance_mock() - - mock_generate_thumbnails.assert_called_once_with( - model=self.instance_mock.__class__, - pk=self.instance_mock.pk, - field="image", - ) - - -class ProductTemplateImageSignalTest(AbstractSignalTest): - def create_instance_mock(self): - return ProductTemplateImage.objects.create( - template=self.template_instance, - image=SimpleUploadedFile("test_image.jpg", b"fake_content"), - is_main=True - ) diff --git a/artel/store/views.py b/artel/store/views.py index 7d21563..988105f 100644 --- a/artel/store/views.py +++ b/artel/store/views.py @@ -53,7 +53,7 @@ class CartView(TemplateView): class CartActionView(ViewSet): - # TODO - test this, currently not in use + # NOTE - currently not in use @action(detail=False, methods=["get"], url_path="list-products") def list_products(self, request): # get cart items @@ -144,7 +144,7 @@ class ConfigureProductSummaryView(View): def post(self, request, variant_pk: int, *args, **kwargs): # Here just send the email with product request variant = Product.objects.get(pk=variant_pk) - send_produt_request_email(variant.pk) + send_produt_request_email.apply_async(args=[variant.pk]) messages.success(request, "Zapytanie o produkt zostało wysłane") context = self.get_context_data(variant_pk) return HttpResponseRedirect(context["store_url"])