Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#783 tests for previously approved content #788

Merged
merged 5 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BackEnd/images/factories.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import factory.fuzzy

from .models import ProfileImage


Expand All @@ -14,5 +13,6 @@ class Meta:
)
content_type = "jpeg"
image_path = factory.django.ImageField(filename="test.jpeg")
hash_md5 = factory.Faker("md5")
is_approved = False
is_deleted = False
1 change: 0 additions & 1 deletion BackEnd/profiles/tests/test_crud_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from images.factories import ProfileimageFactory
from utils.dump_response import dump # noqa
from utils.unittest_helper import AnyInt
from django.core.files.uploadedfile import SimpleUploadedFile


class TestProfileDetailAPIView(APITestCase):
Expand Down
288 changes: 287 additions & 1 deletion BackEnd/profiles/tests/test_email_sending.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
from django.conf import settings
from rest_framework.test import APITestCase
from unittest import mock
from django.utils.timezone import now
Expand All @@ -16,7 +15,17 @@
class TestSendModerationEmail(APITestCase):
def setUp(self):
self.banner = ProfileimageFactory(image_type="banner")
self.previously_approved_banner = ProfileimageFactory(
image_type="banner",
hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5",
is_approved=True,
)
self.logo = ProfileimageFactory(image_type="logo")
self.previously_approved_logo = ProfileimageFactory(
image_type="banner",
hash_md5="b4094f9fa6e298a6e25c1dba791868fe",
is_approved=True,
)
self.user = UserFactory(email="test1@test.com")
self.profile = ProfileStartupFactory.create(
person=self.user,
Expand Down Expand Up @@ -150,6 +159,70 @@ def test_send_moderation_email_new_banner_approved_logo(self):
os.path.basename(self.banner.image_path.name),
)

def test_send_moderation_email_previously_approved_banner(self):
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.banner = new_banner
self.profile.logo = self.logo

manager = ModerationManager(self.profile)
manager.check_for_moderation()
banner = manager.images["banner"]
logo = manager.images["logo"]
content_is_deleted = manager.content_deleted
send_moderation_email(self.profile, banner, logo, content_is_deleted)

self.assertEqual(len(mail.outbox), 1)
email_data = mail.outbox[0]
self.assertEqual(
email_data.subject,
f"{self.profile.name} - {self.profile.status_updated_at.strftime('%d.%m.%Y')}: Запит на затвердження змін в обліковому записі компанії",
)
self.assertIn(self.profile.name, email_data.body)
self.assertIn(
self.profile.status_updated_at.strftime("%d.%m.%Y %H:%M"),
email_data.body,
)

self.assertEqual(len(email_data.attachments), 1)
self.assertEqual(
email_data.attachments[0].get_filename(),
os.path.basename(self.logo.image_path.name),
)

def test_send_moderation_email_previously_approved_logo(self):
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
self.profile.banner = self.banner
self.profile.logo = new_logo

manager = ModerationManager(self.profile)
manager.check_for_moderation()
banner = manager.images["banner"]
logo = manager.images["logo"]
content_is_deleted = manager.content_deleted
send_moderation_email(self.profile, banner, logo, content_is_deleted)

self.assertEqual(len(mail.outbox), 1)
email_data = mail.outbox[0]
self.assertEqual(
email_data.subject,
f"{self.profile.name} - {self.profile.status_updated_at.strftime('%d.%m.%Y')}: Запит на затвердження змін в обліковому записі компанії",
)
self.assertIn(self.profile.name, email_data.body)
self.assertIn(
self.profile.status_updated_at.strftime("%d.%m.%Y %H:%M"),
email_data.body,
)

self.assertEqual(len(email_data.attachments), 1)
self.assertEqual(
email_data.attachments[0].get_filename(),
os.path.basename(self.banner.image_path.name),
)

# test for deleted images
def test_content_deleted_email_with_pending_status(self):
self.profile.status = self.profile.PENDING
Expand Down Expand Up @@ -187,11 +260,92 @@ def test_remove_pending_image_keep_approved_image(self):
self.assertTrue(self.profile.banner.is_approved)
self.assertIsNone(self.profile.logo)

def test_content_deleted_previously_approved_banner(self):
self.profile.banner = self.banner
self.profile.status = self.profile.PENDING
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.banner = new_banner
manager = ModerationManager(self.profile)
manager.check_for_moderation()
banner = manager.images["banner"]
logo = manager.images["logo"]
content_is_deleted = manager.content_deleted
send_moderation_email(self.profile, banner, logo, content_is_deleted)

self.assertIn(
"Інформуємо про те що попередньо доданий контент було видалено користувачем.",
mail.outbox[0].body,
)
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertEqual(self.profile.banner, new_banner)
self.assertIsNone(self.profile.logo)

def test_content_deleted_previously_approved_logo(self):
self.profile.logo = self.logo
self.profile.status = self.profile.PENDING
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
self.profile.logo = new_logo
manager = ModerationManager(self.profile)
manager.check_for_moderation()
banner = manager.images["banner"]
logo = manager.images["logo"]
content_is_deleted = manager.content_deleted
send_moderation_email(self.profile, banner, logo, content_is_deleted)

self.assertIn(
"Інформуємо про те що попередньо доданий контент було видалено користувачем.",
mail.outbox[0].body,
)
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertEqual(self.profile.logo, new_logo)
self.assertIsNone(self.profile.banner)

def test_content_deleted_previously_approved_both(self):
self.profile.banner = self.banner
self.profile.logo = self.logo
self.profile.status = self.profile.PENDING
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.logo = new_logo
self.profile.banner = new_banner
manager = ModerationManager(self.profile)
manager.check_for_moderation()
banner = manager.images["banner"]
logo = manager.images["logo"]
content_is_deleted = manager.content_deleted
send_moderation_email(self.profile, banner, logo, content_is_deleted)

self.assertIn(
"Інформуємо про те що попередньо доданий контент було видалено користувачем.",
mail.outbox[0].body,
)
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertEqual(self.profile.logo, new_logo)
self.assertEqual(self.profile.banner, new_banner)


class TestSendModerationManager(APITestCase):
def setUp(self):
self.banner = ProfileimageFactory(image_type="banner")
self.previously_approved_banner = ProfileimageFactory(
image_type="banner",
hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5",
is_approved=True,
)
self.logo = ProfileimageFactory(image_type="logo")
self.previously_approved_logo = ProfileimageFactory(
image_type="banner",
hash_md5="b4094f9fa6e298a6e25c1dba791868fe",
is_approved=True,
)
self.user = UserFactory(email="test1@test.com")
self.profile = ProfileStartupFactory.create(
person=self.user,
Expand All @@ -210,6 +364,12 @@ def test_needs_moderation_approved_image(self):
self.logo.is_approved = True
self.assertFalse(self.manager.needs_moderation(self.banner))
self.assertFalse(self.manager.needs_moderation(self.logo))
self.assertFalse(
self.manager.needs_moderation(self.previously_approved_banner)
)
self.assertFalse(
self.manager.needs_moderation(self.previously_approved_logo)
)

def test_needs_moderation_deleted_image(self):
self.assertFalse(self.manager.needs_moderation(self.profile.banner))
Expand All @@ -223,6 +383,39 @@ def test_update_pending_status(self, mock_now):
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertTrue(self.manager.moderation_is_needed)

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_update_pending_status_previously_approved_banner(self, mock_now):
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.banner = new_banner
self.manager.update_pending_status("banner", self.profile.banner)
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertFalse(self.manager.moderation_is_needed)

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_update_pending_status_previously_approved_logo(self, mock_now):
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
self.profile.logo = new_logo
self.manager.update_pending_status("logo", self.profile.logo)
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertFalse(self.manager.moderation_is_needed)

def test_previously_approved_content_pending_status(self):
self.profile.banner = self.banner
self.profile.status = self.profile.PENDING
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
self.profile.logo = new_logo
self.manager.update_pending_status("logo", self.profile.logo)
self.assertEqual(self.profile.status, self.profile.PENDING)
self.assertFalse(self.manager.moderation_is_needed)

# cases for moderation is needed
@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_check_for_moderation(self, mock_now):
Expand All @@ -237,6 +430,38 @@ def test_check_for_moderation(self, mock_now):
{"banner": self.banner, "logo": self.logo},
)

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_check_for_moderation_previously_approved_banner(self, mock_now):
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.banner = new_banner
self.profile.logo = self.logo
self.manager.check_for_moderation()
self.assertEqual(self.profile.status, self.profile.PENDING)
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertTrue(self.manager.moderation_is_needed)
self.assertEqual(
self.manager.images,
{"banner": None, "logo": self.logo},
)

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_check_for_moderation_previously_approved_logo(self, mock_now):
self.profile.banner = self.banner
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
self.profile.logo = new_logo
self.manager.check_for_moderation()
self.assertEqual(self.profile.status, self.profile.PENDING)
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertTrue(self.manager.moderation_is_needed)
self.assertEqual(
self.manager.images,
{"banner": self.banner, "logo": None},
)

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_check_for_moderation_empty_banner(self, mock_now):
self.profile.logo = self.logo
Expand Down Expand Up @@ -273,6 +498,32 @@ def test_check_for_moderation_with_approved_image(self, mock_now):
{"banner": None, "logo": self.logo},
)

def test_previously_approved_banner_empty_logo(self):
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.banner = new_banner
self.manager.check_for_moderation()
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertFalse(self.manager.moderation_is_needed)
self.assertEqual(
self.manager.images,
{"banner": None, "logo": None},
)

def test_previously_approved_logo_empty_banner(self):
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
self.profile.logo = new_logo
self.manager.check_for_moderation()
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertFalse(self.manager.moderation_is_needed)
self.assertEqual(
self.manager.images,
{"banner": None, "logo": None},
)

# handle the deletion of a new image
@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_handle_approved_image_status_pending(self, mock_now):
Expand Down Expand Up @@ -318,6 +569,41 @@ def test_undefined_status_after_approved_images_deleted(self):
self.assertFalse(self.manager.content_deleted)
self.assertEqual(self.manager.images, {"banner": None, "logo": None})

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_handle_both_approved(self, mock_now):
self.profile.status = self.profile.PENDING
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.logo = new_logo
self.profile.banner = new_banner
self.manager.check_for_moderation()
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertFalse(self.manager.moderation_is_needed)
self.assertTrue(self.manager.content_deleted)
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertEqual(self.manager.images, {"banner": None, "logo": None})

@mock.patch("utils.moderation.image_moderation.now", return_value=now())
def test_handle_both_approved_pending_status(self, mock_now):
new_logo = ProfileimageFactory(
image_type="logo", hash_md5="b4094f9fa6e298a6e25c1dba791868fe"
)
new_banner = ProfileimageFactory(
image_type="banner", hash_md5="0dc41dd9dcbc75e730642dbfb87cd1d5"
)
self.profile.logo = new_logo
self.profile.banner = new_banner
self.manager.check_for_moderation()
self.assertEqual(self.profile.status, self.profile.APPROVED)
self.assertFalse(self.manager.moderation_is_needed)
self.assertFalse(self.manager.content_deleted)
self.assertEqual(self.profile.status_updated_at, mock_now.return_value)
self.assertEqual(self.manager.images, {"banner": None, "logo": None})


class TestApprovedImagesDeleter(APITestCase):
def setUp(self):
Expand Down
3 changes: 2 additions & 1 deletion BackEnd/utils/moderation/image_moderation.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def handle_both_approved(self):
if self.profile.status == self.profile.PENDING:
self.content_deleted = True
self.profile.status = self.profile.APPROVED
self.profile.status_updated_at = now()
self.profile.save()

def handle_approved_status(self, secondary_image):
Expand Down Expand Up @@ -58,7 +59,7 @@ def update_pending_status(self, image_type, image):
image.save()
if self.profile.status != self.profile.PENDING:
self.profile.status = self.profile.APPROVED
self.profile.status_updated_at = now()
self.profile.status_updated_at = now()
setattr(self.profile, f"{image_type}_approved", image)
self.profile.save()
completeness_count(self.profile)
Expand Down
Loading