Skip to content

Commit

Permalink
Fixed conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderSychev2005 committed Aug 30, 2024
2 parents 14ce1fc + 5d760f3 commit 91556b7
Show file tree
Hide file tree
Showing 61 changed files with 553 additions and 211 deletions.
1 change: 1 addition & 0 deletions .github/workflows/django_cd_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ env:
REACT_APP_BASE_API_URL: ${{ vars.REACT_APP_BASE_API_URL }}
REACT_APP_PUBLIC_URL: ${{ vars.REACT_APP_PUBLIC_URL }}
ALLOWED_ENV_HOST: ${{ vars.ALLOWED_ENV_HOST }}
REDIS_URL: ${{ vars.REDIS_URL }}

jobs:
deploy:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests_be.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ env:
EMAIL_HOST_PASSWORD: Test1234
CORS_ORIGIN_WHITELIST: ''
ALLOWED_ENV_HOST: ''
REDIS_URL: ${{ vars.REDIS_URL }}


jobs:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ env
/.DS_Store
__pycache__/
/FrontEnd/node_modules
django.log

BackEnd/public/*
!BackEnd/public/media/.gitkeep
Expand Down
36 changes: 36 additions & 0 deletions BackEnd/administration/migrations/0003_autoapprovetask.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Generated by Django 4.2.3 on 2024-08-19 15:35

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):
dependencies = [
("profiles", "0021_savedcompany_is_updated"),
("administration", "0002_create_initial_auto_moderation_hours"),
]

operations = [
migrations.CreateModel(
name="AutoapproveTask",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("celery_task_id", models.CharField()),
(
"profile",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="profiles.profile",
),
),
],
),
]
6 changes: 6 additions & 0 deletions BackEnd/administration/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db import models
from django.core.exceptions import ValidationError
from profiles.models import Profile


def validate_auto_moderation_hours(value: int):
Expand All @@ -26,3 +27,8 @@ def get_auto_moderation_hours(cls):
pk=1, defaults={"auto_moderation_hours": 12}
)
return obj


class AutoapproveTask(models.Model):
celery_task_id = models.CharField()
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
3 changes: 3 additions & 0 deletions BackEnd/forum/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .celery import app as celery_app

__all__ = ("celery_app",)
9 changes: 9 additions & 0 deletions BackEnd/forum/celery.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os
from celery import Celery

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "forum.settings")
app = Celery("forum")

app.config_from_object("django.conf:settings", namespace="CELERY")

app.autodiscover_tasks()
34 changes: 34 additions & 0 deletions BackEnd/forum/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@

WSGI_APPLICATION = "forum.wsgi.application"

CELERY_BROKER_URL = config("REDIS_URL")
CELERY_RESULT_BACKEND = config("REDIS_URL")

DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
Expand Down Expand Up @@ -234,3 +237,34 @@ def show_toolbar(request):
DEBUG_TOOLBAR_CONFIG = {
"SHOW_TOOLBAR_CALLBACK": show_toolbar,
}


LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "{levelname} {asctime} {module} {message}",
"style": "{",
},
"simple": {
"format": "{levelname} {message}",
"style": "{",
},
},
"handlers": {
"file": {
"level": "ERROR",
"class": "logging.FileHandler",
"filename": os.path.join(BASE_DIR, "django.log"),
"formatter": "verbose",
},
},
"loggers": {
"utils": {
"handlers": ["file"],
"level": "ERROR",
"propagate": True,
},
},
}
4 changes: 4 additions & 0 deletions BackEnd/profiles/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from images.models import ProfileImage
from utils.regions_ukr_names import get_regions_ukr_names_as_string
from utils.moderation.moderation_action import ModerationAction
from utils.moderation.image_moderation import ModerationManager


class ActivitySerializer(serializers.ModelSerializer):
Expand Down Expand Up @@ -478,6 +479,9 @@ def update(self, instance, validated_data):
else:
raise serializers.ValidationError("Invalid action provided.")

moderation_manager = ModerationManager(profile=instance)
moderation_manager.revoke_deprecated_autoapprove()

instance.status_updated_at = now()
instance.save()
return instance
25 changes: 25 additions & 0 deletions BackEnd/profiles/tasks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from celery import shared_task

from .models import Profile
from images.models import ProfileImage
from utils.completeness_counter import completeness_count


@shared_task
def celery_autoapprove(profile_id, banner_uuid, logo_uuid):
profile = Profile.objects.get(pk=profile_id)
if banner_uuid:
banner = ProfileImage.objects.get(pk=banner_uuid)
banner.is_approved = True
profile.banner_approved = banner
banner.save()

if logo_uuid:
logo = ProfileImage.objects.get(pk=logo_uuid)
logo.is_approved = True
profile.logo_approved = logo
logo.save()

profile.status = profile.AUTOAPPROVED
profile.save()
completeness_count(profile)
2 changes: 1 addition & 1 deletion BackEnd/profiles/templates/profiles/email_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<p>Вам надійшов запит на затвердження змін в обліковому записі компанії {{ profile_name }} на сайті CraftMerge.</p>
<p>Перегляньте зміни та затвердіть або скасуйте їх.</p>
{% else %}
<p>Інформуємо про те що попередньо доданий контент було видалено</p>
<p>Інформуємо про те що попередньо доданий контент було видалено користувачем.</p>
{% endif %}
<p><b>Дата змін: </b>{{ updated_at }} UTC</p>
{% if banner %}
Expand Down
40 changes: 21 additions & 19 deletions BackEnd/profiles/tests/test_approve_moderation_request.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from unittest.mock import patch

from rest_framework import status
from rest_framework.test import APITestCase, APIClient

Expand All @@ -11,9 +13,9 @@
from utils.dump_response import dump # noqa


@patch("profiles.views.ModerationManager.schedule_autoapprove")
class TestProfileModeration(APITestCase):
def setUp(self) -> None:

self.banner = ProfileimageFactory(image_type="banner")
self.logo = ProfileimageFactory(image_type="logo")
self.second_banner = ProfileimageFactory(image_type="banner")
Expand All @@ -26,8 +28,7 @@ def setUp(self) -> None:

self.moderator_client = APIClient()

def test_approve_banner_and_logo(self):

def test_approve_banner_and_logo(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -66,9 +67,9 @@ def test_approve_banner_and_logo(self):
self.assertEqual(self.profile.banner_approved, self.profile.banner)
self.assertEqual(self.profile.logo_approved, self.profile.logo)
self.assertEqual(self.profile.APPROVED, self.profile.status)
mock_manager.assert_called_once()

def test_approve_banner(self):

def test_approve_banner(self, mock_manager):
# user updates only banner
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -102,9 +103,9 @@ def test_approve_banner(self):
self.assertTrue(self.banner.is_approved)
self.assertEqual(self.profile.banner_approved, self.profile.banner)
self.assertEqual(self.profile.APPROVED, self.profile.status)
mock_manager.assert_called_once()

def test_approve_logo(self):

def test_approve_logo(self, mock_manager):
# user updates logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -138,9 +139,9 @@ def test_approve_logo(self):
self.assertTrue(self.logo.is_approved)
self.assertEqual(self.profile.logo_approved, self.profile.logo)
self.assertEqual(self.profile.APPROVED, self.profile.status)
mock_manager.assert_called_once()

def test_approve_banner_and_logo_processed_request(self):

def test_approve_banner_and_logo_processed_request(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -186,9 +187,9 @@ def test_approve_banner_and_logo_processed_request(self):
},
response.json(),
)
mock_manager.assert_called_once()

def test_approve_banner_and_logo_outdated_request(self):

def test_approve_banner_and_logo_outdated_request(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -241,9 +242,9 @@ def test_approve_banner_and_logo_outdated_request(self):
self.assertNotEqual(self.profile.banner, first_banner)
self.assertNotEqual(self.profile.logo, first_logo)
self.assertEqual(self.profile.PENDING, self.profile.status)
mock_manager.assert_called()

def test_approve_banner_and_logo_wrong_action(self):

def test_approve_banner_and_logo_wrong_action(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -272,9 +273,9 @@ def test_approve_banner_and_logo_wrong_action(self):
self.assertEqual(
{"action": ["Action is not allowed"]}, response.json()
)
mock_manager.assert_called_once()

def test_approve_banner_and_logo_error_in_signed_id(self):

def test_approve_banner_and_logo_error_in_signed_id(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand All @@ -301,9 +302,9 @@ def test_approve_banner_and_logo_error_in_signed_id(self):

self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
self.assertEqual({"detail": "Not found."}, response.json())
mock_manager.assert_called_once()

def test_approve_banner_and_logo_non_existing_profile(self):

def test_approve_banner_and_logo_non_existing_profile(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand All @@ -330,9 +331,9 @@ def test_approve_banner_and_logo_non_existing_profile(self):

self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)
self.assertEqual({"detail": "Not found."}, response.json())
mock_manager.assert_called_once()

def test_approve_banner_and_logo_empty_image_fields(self):

def test_approve_banner_and_logo_empty_image_fields(self, mock_manager):
# user updates both banner and logo
self.user_client.patch(
path="/api/profiles/{profile_id}".format(
Expand Down Expand Up @@ -364,3 +365,4 @@ def test_approve_banner_and_logo_empty_image_fields(self):
},
response.json(),
)
mock_manager.assert_called_once()
8 changes: 7 additions & 1 deletion BackEnd/profiles/tests/test_crud_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,12 +786,17 @@ def test_full_update_profile_authorized_with_partial_data(self):
)
self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)

@mock.patch(
"utils.moderation.image_moderation.ModerationManager.schedule_autoapprove"
)
@mock.patch(
"utils.moderation.send_email.attach_image",
new_callable=mock.mock_open,
read_data=b"image",
)
def test_full_update_profile_authorized_with_full_data(self, mock_file):
def test_full_update_profile_authorized_with_full_data(
self, mock_file, mock_autoapprove
):
category = CategoryFactory()
activity = ActivityFactory()
region = RegionFactory()
Expand Down Expand Up @@ -826,6 +831,7 @@ def test_full_update_profile_authorized_with_full_data(self, mock_file):
status.HTTP_200_OK, response.status_code, response.content
)
mock_file.assert_called()
mock_autoapprove.assert_called_once()

def test_full_update_profile_unauthorized(self):
category = CategoryFactory()
Expand Down
Loading

0 comments on commit 91556b7

Please sign in to comment.