From 9f38a7636da9e0d3f995a45ac24a9fc8324d1aff Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Tue, 27 Aug 2024 10:55:26 +0300 Subject: [PATCH 1/7] tests for removed content --- BackEnd/profiles/tests/test_email_sending.py | 138 +++++++++++++++++-- 1 file changed, 124 insertions(+), 14 deletions(-) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index f27d27663..e0fe4368a 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -23,6 +23,7 @@ def setUp(self): edrpou="99999999", ) + # tests for new images def test_send_moderation_email(self): self.profile.banner = self.banner self.profile.logo = self.logo @@ -114,6 +115,69 @@ def test_send_moderation_email_only_logo(self): os.path.basename(self.logo.image_path.name), ) + def test_send_moderation_email_new_banner_approved_logo(self): + self.profile.banner = self.banner + self.profile.logo = self.logo + self.profile.logo.is_approved = True + + 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 + 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.UNDEFINED) + + def test_remove_pending_image_keep_approved_image(self): + self.profile.banner = self.banner + self.profile.banner.is_approved = True + self.profile.status = self.profile.PENDING + 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) + class TestSendModerationManager(APITestCase): def setUp(self): @@ -139,24 +203,23 @@ def test_needs_moderation_approved_image(self): self.assertFalse(self.manager.needs_moderation(self.logo)) def test_needs_moderation_deleted_image(self): - self.profile.banner = None - self.profile.logo = None self.assertFalse(self.manager.needs_moderation(self.profile.banner)) self.assertFalse(self.manager.needs_moderation(self.profile.logo)) @mock.patch("utils.moderation.image_moderation.now", return_value=now()) def test_update_pending_status(self, mock_now): self.manager.update_pending_status() - self.assertEqual(self.profile.status, "pending") + 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) + # cases for moderation is needed @mock.patch("utils.moderation.image_moderation.now", return_value=now()) def test_check_for_moderation(self, mock_now): self.profile.banner = self.banner self.profile.logo = self.logo self.manager.check_for_moderation() - self.assertEqual(self.profile.status, "pending") + 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( @@ -165,11 +228,10 @@ def test_check_for_moderation(self, mock_now): ) @mock.patch("utils.moderation.image_moderation.now", return_value=now()) - def test_check_for_moderation_deleted_banner(self, mock_now): - self.profile.banner = None + def test_check_for_moderation_empty_banner(self, mock_now): self.profile.logo = self.logo self.manager.check_for_moderation() - self.assertEqual(self.profile.status, "pending") + 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( @@ -177,21 +239,69 @@ def test_check_for_moderation_deleted_banner(self, mock_now): ) @mock.patch("utils.moderation.image_moderation.now", return_value=now()) - def test_check_for_moderation_deleted_logo(self, mock_now): + def test_check_for_moderation_empty_logo(self, mock_now): self.profile.banner = self.banner - self.profile.logo = None self.manager.check_for_moderation() - self.assertEqual(self.profile.status, "pending") + 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} ) - # needs improvement for undefined status - def test_check_for_moderation_deleted_both(self): - self.profile.banner = None - self.profile.logo = None + @mock.patch("utils.moderation.image_moderation.now", return_value=now()) + def test_check_for_moderation_with_approved_image(self, mock_now): + self.profile.banner = self.banner + self.profile.banner.is_approved = True + 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_handle_approved_image_status_pending(self, mock_now): + self.profile.banner = self.banner + self.profile.banner.is_approved = True + self.profile.status = self.profile.PENDING + self.manager.check_for_moderation() + 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) + self.assertTrue(self.manager.content_deleted) + self.assertEqual( + self.manager.images, + {"banner": None, "logo": None}, + ) + + def test_handle_approved_image_status_approved(self): + self.profile.banner = self.banner + self.profile.banner.is_approved = True + self.profile.status = self.profile.APPROVED + 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_handle_undefined_status(self): + self.profile.status = self.profile.PENDING + self.manager.check_for_moderation() + self.assertEqual(self.profile.status, self.profile.UNDEFINED) + self.assertFalse(self.manager.moderation_is_needed) + self.assertTrue(self.manager.content_deleted) + self.assertEqual(self.manager.images, {"banner": None, "logo": None}) + + def test_handle_undefined_status_deletion_after_approve(self): + self.profile.status = self.profile.APPROVED self.manager.check_for_moderation() + self.assertEqual(self.profile.status, self.profile.UNDEFINED) self.assertFalse(self.manager.moderation_is_needed) + self.assertFalse(self.manager.content_deleted) self.assertEqual(self.manager.images, {"banner": None, "logo": None}) From 0e13592f4572158daee85427caaa8366cf14369e Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Tue, 27 Aug 2024 21:16:56 +0300 Subject: [PATCH 2/7] test for approved images deleter --- BackEnd/profiles/tests/test_email_sending.py | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index e0fe4368a..a4435382c 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -4,6 +4,7 @@ from unittest import mock from django.utils.timezone import now from django.core import mail +from utils.moderation.handle_approved_images import ApprovedImagesDeleter from utils.moderation.send_email import send_moderation_email from utils.moderation.image_moderation import ModerationManager from authentication.factories import UserFactory @@ -305,3 +306,29 @@ def test_handle_undefined_status_deletion_after_approve(self): self.assertFalse(self.manager.moderation_is_needed) self.assertFalse(self.manager.content_deleted) self.assertEqual(self.manager.images, {"banner": None, "logo": None}) + + +class TestApprovedImagesDeleter(APITestCase): + def setUp(self): + self.banner = ProfileimageFactory(image_type="banner") + self.logo = ProfileimageFactory(image_type="logo") + self.user = UserFactory(email="test1@test.com") + self.profile = ProfileStartupFactory.create( + person=self.user, + official_name="Test Official Startup", + phone="380100102034", + edrpou="99999999", + ) + self.deletion_checker = ApprovedImagesDeleter(self.profile) + + def test_handle_potential_deletion_banner(self): + self.profile.banner_approved = self.banner + self.profile.status = self.profile.PENDING + self.deletion_checker.handle_potential_deletion() + self.assertTrue(self.profile.banner_approved.is_deleted) + + def test_handle_potential_deletion_logo(self): + self.profile.logo_approved = self.logo + self.profile.status = self.profile.PENDING + self.deletion_checker.handle_potential_deletion() + self.assertTrue(self.profile.logo_approved.is_deleted) \ No newline at end of file From 8924def047fbaf1e45585f5143020b88deddb98d Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Fri, 30 Aug 2024 11:54:09 +0300 Subject: [PATCH 3/7] comments for two tests --- BackEnd/profiles/tests/test_email_sending.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index a4435382c..5a780fb7f 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -264,6 +264,7 @@ def test_check_for_moderation_with_approved_image(self, mock_now): {"banner": None, "logo": self.logo}, ) + # 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): self.profile.banner = self.banner @@ -279,6 +280,7 @@ def test_handle_approved_image_status_pending(self, mock_now): {"banner": None, "logo": None}, ) + # handle the deletion one of an approved images def test_handle_approved_image_status_approved(self): self.profile.banner = self.banner self.profile.banner.is_approved = True @@ -299,7 +301,7 @@ def test_handle_undefined_status(self): self.assertTrue(self.manager.content_deleted) self.assertEqual(self.manager.images, {"banner": None, "logo": None}) - def test_handle_undefined_status_deletion_after_approve(self): + def test_undefined_status_after_approved_images_deleted(self): self.profile.status = self.profile.APPROVED self.manager.check_for_moderation() self.assertEqual(self.profile.status, self.profile.UNDEFINED) From dec0fedaf3321f1fa8f44d234acc60754cb97f8a Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Fri, 30 Aug 2024 11:56:09 +0300 Subject: [PATCH 4/7] black formatting --- BackEnd/profiles/tests/test_email_sending.py | 2 +- .../profiles/tests/test_reject_moderation_request.py | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index 5a780fb7f..86b99c970 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -333,4 +333,4 @@ def test_handle_potential_deletion_logo(self): self.profile.logo_approved = self.logo self.profile.status = self.profile.PENDING self.deletion_checker.handle_potential_deletion() - self.assertTrue(self.profile.logo_approved.is_deleted) \ No newline at end of file + self.assertTrue(self.profile.logo_approved.is_deleted) diff --git a/BackEnd/profiles/tests/test_reject_moderation_request.py b/BackEnd/profiles/tests/test_reject_moderation_request.py index 6742ac234..5b4ea0839 100644 --- a/BackEnd/profiles/tests/test_reject_moderation_request.py +++ b/BackEnd/profiles/tests/test_reject_moderation_request.py @@ -13,7 +13,6 @@ 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") @@ -29,7 +28,6 @@ def setUp(self) -> None: self.unregistered_user_client = APIClient() def test_reject_banner_and_logo(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -71,7 +69,6 @@ def test_reject_banner_and_logo(self): self.assertFalse(self.user.is_active) def test_reject_banner(self): - # user updates only banner self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -109,7 +106,6 @@ def test_reject_banner(self): self.assertFalse(self.user.is_active) def test_reject_logo(self): - # user updates logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -147,7 +143,6 @@ def test_reject_logo(self): self.assertFalse(self.user.is_active) def test_reject_banner_and_logo_processed_request(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -195,7 +190,6 @@ def test_reject_banner_and_logo_processed_request(self): ) def test_reject_banner_and_logo_outdated_request(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -248,7 +242,6 @@ def test_reject_banner_and_logo_outdated_request(self): self.assertEqual(self.profile.PENDING, self.profile.status) def test_reject_banner_and_logo_wrong_action(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -279,7 +272,6 @@ def test_reject_banner_and_logo_wrong_action(self): ) def test_reject_banner_and_logo_error_in_signed_id(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -308,7 +300,6 @@ def test_reject_banner_and_logo_error_in_signed_id(self): self.assertEqual({"detail": "Not found."}, response.json()) def test_reject_banner_and_logo_non_existing_profile(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -337,7 +328,6 @@ def test_reject_banner_and_logo_non_existing_profile(self): self.assertEqual({"detail": "Not found."}, response.json()) def test_reject_banner_and_logo_empty_image_fields(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -370,7 +360,6 @@ def test_reject_banner_and_logo_empty_image_fields(self): ) def test_login_blocked_user_due_to_rejected_request(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( @@ -413,7 +402,6 @@ def test_login_blocked_user_due_to_rejected_request(self): ) def test_register_blocked_user_due_to_rejected_request(self): - # user updates both banner and logo self.user_client.patch( path="/api/profiles/{profile_id}".format( From 0234882beb0cbdc3a24c94839066d23aaf365d04 Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Sat, 31 Aug 2024 18:44:36 +0300 Subject: [PATCH 5/7] updated tests for ApprovedImagesDeleter --- BackEnd/profiles/tests/test_email_sending.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index 86b99c970..55267a5c8 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -314,22 +314,32 @@ class TestApprovedImagesDeleter(APITestCase): def setUp(self): self.banner = ProfileimageFactory(image_type="banner") self.logo = ProfileimageFactory(image_type="logo") + self.banner_approved = ProfileimageFactory(image_type="banner", is_approved=True) + self.logo_approved = ProfileimageFactory(image_type="logo", is_approved=True) self.user = UserFactory(email="test1@test.com") self.profile = ProfileStartupFactory.create( person=self.user, official_name="Test Official Startup", phone="380100102034", edrpou="99999999", + banner=self.banner, + logo=self.logo, + banner_approved=self.banner_approved, + logo_approved=self.logo_approved ) self.deletion_checker = ApprovedImagesDeleter(self.profile) + # user removes banner from profile def test_handle_potential_deletion_banner(self): + self.profile.banner = None self.profile.banner_approved = self.banner self.profile.status = self.profile.PENDING self.deletion_checker.handle_potential_deletion() self.assertTrue(self.profile.banner_approved.is_deleted) + # user removes logo from profile def test_handle_potential_deletion_logo(self): + self.profile.logo = None self.profile.logo_approved = self.logo self.profile.status = self.profile.PENDING self.deletion_checker.handle_potential_deletion() From af7d2eaf286104df5221f79a2183d0c952605605 Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Sat, 31 Aug 2024 18:46:22 +0300 Subject: [PATCH 6/7] black formatting --- BackEnd/profiles/tests/test_email_sending.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index 55267a5c8..9ff4b7a39 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -314,8 +314,12 @@ class TestApprovedImagesDeleter(APITestCase): def setUp(self): self.banner = ProfileimageFactory(image_type="banner") self.logo = ProfileimageFactory(image_type="logo") - self.banner_approved = ProfileimageFactory(image_type="banner", is_approved=True) - self.logo_approved = ProfileimageFactory(image_type="logo", is_approved=True) + self.banner_approved = ProfileimageFactory( + image_type="banner", is_approved=True + ) + self.logo_approved = ProfileimageFactory( + image_type="logo", is_approved=True + ) self.user = UserFactory(email="test1@test.com") self.profile = ProfileStartupFactory.create( person=self.user, @@ -325,7 +329,7 @@ def setUp(self): banner=self.banner, logo=self.logo, banner_approved=self.banner_approved, - logo_approved=self.logo_approved + logo_approved=self.logo_approved, ) self.deletion_checker = ApprovedImagesDeleter(self.profile) From 746ead9e8d8cd89a1993c54ff4dd336be82f4465 Mon Sep 17 00:00:00 2001 From: Andrewakiv Date: Mon, 2 Sep 2024 00:26:36 +0300 Subject: [PATCH 7/7] added banner and logo check --- BackEnd/profiles/tests/test_email_sending.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BackEnd/profiles/tests/test_email_sending.py b/BackEnd/profiles/tests/test_email_sending.py index 9ff4b7a39..c8ceb76fe 100644 --- a/BackEnd/profiles/tests/test_email_sending.py +++ b/BackEnd/profiles/tests/test_email_sending.py @@ -161,6 +161,8 @@ def test_content_deleted_email_with_pending_status(self): mail.outbox[0].body, ) self.assertEqual(self.profile.status, self.profile.UNDEFINED) + self.assertIsNone(self.profile.banner) + self.assertIsNone(self.profile.logo) def test_remove_pending_image_keep_approved_image(self): self.profile.banner = self.banner @@ -178,6 +180,8 @@ def test_remove_pending_image_keep_approved_image(self): mail.outbox[0].body, ) self.assertEqual(self.profile.status, self.profile.APPROVED) + self.assertTrue(self.profile.banner.is_approved) + self.assertIsNone(self.profile.logo) class TestSendModerationManager(APITestCase):