Skip to content

Commit

Permalink
unit tests & coverage 🌟
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlo-mk committed Dec 21, 2024
1 parent 02cc948 commit eba4ebd
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@
],
'totalCount': 1
},
'availablePaymentRecordsCount': 0,
'canCreateFollowUp': False,
'canSendToPaymentGateway': False,
'canSplit': False,
'currencyName': 'Polish złoty',
'dispersionEndDate': '2020-12-10',
'dispersionStartDate': '2020-08-10',
'exchangeRate': 2.0,
Expand All @@ -51,16 +55,44 @@
],
'femaleAdultsCount': 0,
'femaleChildrenCount': 1,
'hasFspDeliveryMechanismXlsxTemplate': False,
'hasPaymentListExportFile': False,
'importedFileName': '',
'maleAdultsCount': 0,
'maleChildrenCount': 1,
'paymentItems': {
'totalCount': 2
},
'paymentsConflictsCount': 1,
'program': {
'name': 'Test All PP QS'
},
'programCycle': {
'endDate': '2020-11-10',
'startDate': '2020-09-10'
},
'splitChoices': [
{
'name': 'By Admin Area 1',
'value': 'BY_ADMIN_AREA1'
},
{
'name': 'By Admin Area 2',
'value': 'BY_ADMIN_AREA2'
},
{
'name': 'By Admin Area 3',
'value': 'BY_ADMIN_AREA3'
},
{
'name': 'By Collector',
'value': 'BY_COLLECTOR'
},
{
'name': 'By Records',
'value': 'BY_RECORDS'
}
],
'status': 'OPEN',
'supportingDocuments': [
{
Expand All @@ -77,7 +109,11 @@
'totalIndividualsCount': 2,
'totalUndeliveredQuantity': 50.0,
'totalUndeliveredQuantityUsd': 100.0,
'unicefId': 'PP-01'
'unicefId': 'PP-01',
'unsuccessfulPaymentsCount': 0,
'verificationPlans': {
'totalCount': 0
}
}
},
{
Expand All @@ -87,7 +123,11 @@
],
'totalCount': 0
},
'availablePaymentRecordsCount': 0,
'canCreateFollowUp': False,
'canSendToPaymentGateway': False,
'canSplit': False,
'currencyName': 'Ukrainian hryvnia',
'dispersionEndDate': '2020-10-10',
'dispersionStartDate': '2020-10-10',
'exchangeRate': 2.0,
Expand All @@ -97,16 +137,44 @@
],
'femaleAdultsCount': 1,
'femaleChildrenCount': 0,
'hasFspDeliveryMechanismXlsxTemplate': False,
'hasPaymentListExportFile': False,
'importedFileName': '',
'maleAdultsCount': 1,
'maleChildrenCount': 0,
'paymentItems': {
'totalCount': 2
},
'paymentsConflictsCount': 0,
'program': {
'name': 'Test All PP QS'
},
'programCycle': {
'endDate': '2020-11-10',
'startDate': '2020-09-10'
},
'splitChoices': [
{
'name': 'By Admin Area 1',
'value': 'BY_ADMIN_AREA1'
},
{
'name': 'By Admin Area 2',
'value': 'BY_ADMIN_AREA2'
},
{
'name': 'By Admin Area 3',
'value': 'BY_ADMIN_AREA3'
},
{
'name': 'By Collector',
'value': 'BY_COLLECTOR'
},
{
'name': 'By Records',
'value': 'BY_RECORDS'
}
],
'status': 'LOCKED',
'supportingDocuments': [
],
Expand All @@ -120,7 +188,11 @@
'totalIndividualsCount': 2,
'totalUndeliveredQuantity': 50.0,
'totalUndeliveredQuantityUsd': 100.0,
'unicefId': 'PP-02'
'unicefId': 'PP-02',
'unsuccessfulPaymentsCount': 0,
'verificationPlans': {
'totalCount': 0
}
}
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
'data': {
'createFollowUpPaymentPlan': {
'paymentPlan': {
'canCreateFollowUp': False,
'isFollowUp': True,
'status': 'OPEN'
'status': 'OPEN',
'totalWithdrawnHouseholdsCount': 0
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions tests/unit/apps/payment/test_all_payment_plan_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,24 @@ class TestPaymentPlanQueries(APITestCase):
}
}
canCreateFollowUp
canSplit
canSendToPaymentGateway
unsuccessfulPaymentsCount
hasFspDeliveryMechanismXlsxTemplate
availablePaymentRecordsCount
importedFileName
hasPaymentListExportFile
currencyName
verificationPlans{
totalCount
}
program{
name
}
splitChoices{
name
value
}
dispersionEndDate
dispersionStartDate
exchangeRate
Expand Down Expand Up @@ -254,6 +272,7 @@ def setUpTestData(cls) -> None:

with freeze_time("2020-10-10"):
program = RealProgramFactory(
name="Test All PP QS",
cycle__start_date=timezone.datetime(2020, 9, 10, tzinfo=utc).date(),
cycle__end_date=timezone.datetime(2020, 11, 10, tzinfo=utc).date(),
)
Expand All @@ -265,6 +284,7 @@ def setUpTestData(cls) -> None:
dispersion_end_date=datetime(2020, 12, 10),
is_follow_up=False,
created_by=cls.user,
currency="PLN",
)
cls.pp.unicef_id = "PP-01"
cls.pp.save()
Expand Down Expand Up @@ -306,6 +326,7 @@ def setUpTestData(cls) -> None:
dispersion_start_date=cls.pp.dispersion_start_date + relativedelta(months=2),
dispersion_end_date=cls.pp.dispersion_end_date - relativedelta(months=2),
created_by=cls.user,
currency="UAH",
)
cls.pp_conflicted.unicef_id = "PP-02"
cls.pp_conflicted.save()
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/apps/payment/test_create_follow_up_payment_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
paymentPlan {
status
isFollowUp
canCreateFollowUp
totalWithdrawnHouseholdsCount
}
}
}
Expand Down
146 changes: 143 additions & 3 deletions tests/unit/apps/payment/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
from unittest.mock import MagicMock, patch

from django import forms
from django.contrib.admin.options import get_content_type_for_model
from django.core.exceptions import ValidationError
from django.core.files.base import ContentFile
from django.db import models
from django.db.utils import IntegrityError
from django.test import TestCase
Expand All @@ -16,7 +18,7 @@
from hct_mis_api.apps.account.fixtures import BusinessAreaFactory, UserFactory
from hct_mis_api.apps.core.currencies import USDC
from hct_mis_api.apps.core.fixtures import DataCollectingTypeFactory, create_afghanistan
from hct_mis_api.apps.core.models import BusinessArea, DataCollectingType
from hct_mis_api.apps.core.models import BusinessArea, DataCollectingType, FileTemp
from hct_mis_api.apps.geo.fixtures import AreaFactory, AreaTypeFactory, CountryFactory
from hct_mis_api.apps.household.fixtures import (
DocumentFactory,
Expand Down Expand Up @@ -256,6 +258,10 @@ def test_can_be_locked(self) -> None:
PaymentFactory(parent=pp1, conflicted=False, currency="PLN")
self.assertEqual(pp1.can_be_locked, True)

def test_is_population_finalized(self) -> None:
payment_plan = PaymentPlanFactory(created_by=self.user, status=PaymentPlan.Status.TP_PROCESSING)
self.assertTrue(payment_plan.is_population_finalized())

def test_get_exchange_rate_for_usdc_currency(self) -> None:
pp = PaymentPlanFactory(currency=USDC, created_by=self.user)
self.assertEqual(pp.get_exchange_rate(), 1.0)
Expand Down Expand Up @@ -333,14 +339,57 @@ def test_payment_plan_has_empty_ids_criteria_property(self) -> None:

self.assertTrue(pp.has_empty_ids_criteria)

def test_remove_export_file_entitlement(self) -> None:
pp = PaymentPlanFactory(created_by=self.user, status=PaymentPlan.Status.LOCKED)
file_temp = FileTemp.objects.create(
object_id=pp.pk,
content_type=get_content_type_for_model(pp),
created=timezone.now(),
file=ContentFile(b"abc", "Test_123.xlsx"),
)
pp.export_file_entitlement = file_temp
pp.save()
pp.refresh_from_db()
self.assertTrue(pp.has_export_file)
self.assertEqual(pp.export_file_entitlement.pk, file_temp.pk)

pp.remove_export_file_entitlement()
pp.save()
pp.refresh_from_db()
self.assertFalse(pp.has_export_file)
self.assertIsNone(pp.export_file_entitlement)

def test_remove_imported_file(self) -> None:
pp = PaymentPlanFactory(
created_by=self.user, status=PaymentPlan.Status.LOCKED, imported_file_date=timezone.now()
)
file_temp = FileTemp.objects.create(
object_id=pp.pk,
content_type=get_content_type_for_model(pp),
created=timezone.now(),
file=ContentFile(b"abc", "Test_777.xlsx"),
)
pp.imported_file = file_temp
pp.save()
pp.refresh_from_db()
self.assertEqual(pp.imported_file.pk, file_temp.pk)
self.assertEqual(pp.imported_file_name, "Test_777.xlsx")

pp.remove_imported_file()
pp.save()
pp.refresh_from_db()
self.assertEqual(pp.imported_file_name, "")
self.assertIsNone(pp.imported_file)
self.assertIsNone(pp.imported_file_date)


class TestPaymentModel(TestCase):
@classmethod
def setUpTestData(cls) -> None:
super().setUpTestData()
create_afghanistan()
cls.business_area = create_afghanistan()
cls.user = UserFactory()
cls.business_area = BusinessArea.objects.get(slug="afghanistan")
cls.pp = PaymentPlanFactory(created_by=cls.user)

def test_create(self) -> None:
p1 = PaymentFactory()
Expand All @@ -354,6 +403,97 @@ def test_unique_together(self) -> None:
with self.assertRaises(IntegrityError):
PaymentFactory(parent=pp, household=hh1, currency="PLN")

def test_payment_status_property(self) -> None:
payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_PENDING)
self.assertEqual(payment.payment_status, "Pending")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_DISTRIBUTION_SUCCESS)
self.assertEqual(payment.payment_status, "Delivered Fully")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_SUCCESS)
self.assertEqual(payment.payment_status, "Delivered Fully")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_DISTRIBUTION_PARTIAL)
self.assertEqual(payment.payment_status, "Delivered Partially")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_NOT_DISTRIBUTED)
self.assertEqual(payment.payment_status, "Not Delivered")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_ERROR)
self.assertEqual(payment.payment_status, "Unsuccessful")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_FORCE_FAILED)
self.assertEqual(payment.payment_status, "Force Failed")

payment = PaymentFactory(parent=self.pp, status=Payment.STATUS_MANUALLY_CANCELLED)
self.assertEqual(payment.payment_status, "-")

def test_mark_as_failed(self) -> None:
payment_invalid_status = PaymentFactory(parent=self.pp, status=Payment.STATUS_FORCE_FAILED)
payment = PaymentFactory(
parent=self.pp,
entitlement_quantity=999,
delivered_quantity=111,
delivered_quantity_usd=22,
status=Payment.STATUS_DISTRIBUTION_PARTIAL,
)
with self.assertRaises(ValidationError) as e:
payment_invalid_status.mark_as_failed()
self.assertIn("Status shouldn't be failed", e.exception)

payment.mark_as_failed()
payment.save()
payment.refresh_from_db()
self.assertEqual(payment.delivered_quantity, 0)
self.assertEqual(payment.delivered_quantity_usd, 0)
self.assertIsNone(payment.delivery_date)
self.assertEqual(payment.status, Payment.STATUS_FORCE_FAILED)

def test_revert_mark_as_failed(self) -> None:
payment_entitlement_quantity_none = PaymentFactory(
parent=self.pp,
entitlement_quantity=None,
entitlement_quantity_usd=None,
delivered_quantity=None,
delivered_quantity_usd=None,
status=Payment.STATUS_FORCE_FAILED,
)
payment_invalid_status = PaymentFactory(parent=self.pp, entitlement_quantity=999, status=Payment.STATUS_PENDING)
payment = PaymentFactory(
parent=self.pp, entitlement_quantity=999, delivered_quantity=111, status=Payment.STATUS_FORCE_FAILED
)
date = timezone.now().date()

with self.assertRaises(ValidationError) as e:
payment_invalid_status.revert_mark_as_failed(999, date)
self.assertIn("Only payment marked as force failed can be reverted", e.exception)

with self.assertRaises(ValidationError) as e:
payment_entitlement_quantity_none.revert_mark_as_failed(999, date)
self.assertIn("Entitlement quantity need to be set in order to revert", e.exception)

payment.revert_mark_as_failed(999, date)
payment.save()
payment.refresh_from_db()
self.assertEqual(payment.delivered_quantity, 999)
self.assertEqual(payment.delivery_date.date(), date)
self.assertEqual(payment.status, Payment.STATUS_DISTRIBUTION_SUCCESS)

def test_get_revert_mark_as_failed_status(self) -> None:
payment = PaymentFactory(parent=self.pp, entitlement_quantity=999)
delivered_quantity_with_status = (
(0, Payment.STATUS_NOT_DISTRIBUTED),
(100, Payment.STATUS_DISTRIBUTION_PARTIAL),
(999, Payment.STATUS_DISTRIBUTION_SUCCESS),
)
for delivered_quantity, status in delivered_quantity_with_status:
result_status = payment.get_revert_mark_as_failed_status(delivered_quantity)
self.assertEqual(result_status, status)

with self.assertRaises(ValidationError) as e:
payment.get_revert_mark_as_failed_status(1000)
self.assertIn("Wrong delivered quantity 1000 for entitlement quantity 999", e.exception)

def test_manager_annotations_pp_conflicts(self) -> None:
program = RealProgramFactory()
program_cycle = program.cycles.first()
Expand Down
Loading

0 comments on commit eba4ebd

Please sign in to comment.