Skip to content

Commit cce5415

Browse files
committed
Allocation model get_information tests
Signed-off-by: Eric Butcher <107886303+Eric-Butcher@users.noreply.github.com>
1 parent d0e3291 commit cce5415

File tree

1 file changed

+131
-8
lines changed

1 file changed

+131
-8
lines changed

coldfront/core/allocation/tests/test_models.py

Lines changed: 131 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66

77
import datetime
88
from django.utils import timezone
9-
9+
from django.utils.html import escape, format_html
1010
from django.core.exceptions import ValidationError
1111
from django.test import TestCase, override_settings
1212
from django.utils.safestring import SafeString
13-
14-
from coldfront.core.allocation.models import Allocation, AllocationStatusChoice
13+
from unittest.mock import patch
14+
from coldfront.core.allocation.models import Allocation, AllocationStatusChoice, AllocationAttribute
1515
from coldfront.core.project.models import Project
1616
from coldfront.core.test_helpers.factories import (
1717
AllocationFactory,
1818
AllocationStatusChoiceFactory,
19+
AllocationAttributeFactory,
20+
AllocationAttributeTypeFactory,
21+
AAttributeTypeFactory,
22+
AllocationAttributeUsageFactory,
1923
ProjectFactory,
2024
ResourceFactory,
2125
)
@@ -143,7 +147,6 @@ def test_status_is_active_and_start_date_equals_end_date_no_error(self):
143147

144148
class AllocationFuncOnExpireException(Exception):
145149
"""Custom exception for testing allocation expiration function in the AllocationModelSaveMethodTests class."""
146-
147150
pass
148151

149152

@@ -162,12 +165,10 @@ def get_dotted_path(func):
162165

163166
def count_invocations(*args, **kwargs):
164167
count_invocations.invocation_count = getattr(count_invocations, "invocation_count", 0) + 1
165-
pass
166168

167169

168170
def count_invocations_negative(*args, **kwargs):
169171
count_invocations_negative.invocation_count = getattr(count_invocations_negative, "invocation_count", 0) - 1
170-
pass
171172

172173

173174
def list_of_same_expire_funcs(func: callable, size=NUMBER_OF_INVOCATIONS) -> list[str]:
@@ -296,5 +297,127 @@ def test_multiple_new_allocations_are_in_database(self):
296297

297298

298299
class AllocationModelExpiresInTests(TestCase):
299-
# going to skip ths until I know how datetimes should be handled
300-
...
300+
301+
mocked_today = datetime.date(2025, 1, 1)
302+
three_years_after_mocked_today = datetime.date(2028, 1, 1)
303+
four_years_after_mocked_today = datetime.date(2029, 1, 1)
304+
305+
def test_end_date_is_today_returns_zero(self):
306+
"""Test that the expires_in method returns 0 when the end date is today."""
307+
allocation: Allocation = AllocationFactory(end_date=timezone.now().date())
308+
self.assertEqual(allocation.expires_in, 0)
309+
310+
def test_end_date_tomorrow_returns_one(self):
311+
"""Test that the expires_in method returns 1 when the end date is tomorrow."""
312+
tomorrow: datetime.date = (timezone.now() + datetime.timedelta(days=1)).date()
313+
allocation: Allocation = AllocationFactory(end_date=tomorrow)
314+
self.assertEqual(allocation.expires_in, 1)
315+
316+
def test_end_date_yesterday_returns_negative_one(self):
317+
"""Test that the expires_in method returns -1 when the end date is yesterday."""
318+
yesterday: datetime.date = (timezone.now() - datetime.timedelta(days=1)).date()
319+
allocation: Allocation = AllocationFactory(end_date=yesterday)
320+
self.assertEqual(allocation.expires_in, -1)
321+
322+
def test_end_date_one_week_ago_returns_negative_seven(self):
323+
"""Test that the expires_in method returns -7 when the end date is one week ago."""
324+
days_in_a_week: int = 7
325+
one_week_ago: datetime.date = (timezone.now() - datetime.timedelta(days=days_in_a_week)).date()
326+
allocation: Allocation = AllocationFactory(end_date=one_week_ago)
327+
self.assertEqual(allocation.expires_in, -days_in_a_week)
328+
329+
def test_end_date_in_one_week_returns_seven(self):
330+
"""Test that the expires_in method returns 7 when the end date is in one week."""
331+
days_in_a_week: int = 7
332+
one_week_from_now: datetime.date = (timezone.now() + datetime.timedelta(days=days_in_a_week)).date()
333+
allocation: Allocation = AllocationFactory(end_date=one_week_from_now)
334+
self.assertEqual(allocation.expires_in, days_in_a_week)
335+
336+
def test_end_date_in_three_years_without_leap_day_returns_days_including_no_leap_day(self):
337+
"""Test that the expires_in method returns the correct number of days in three years when those years did not have a leap year."""
338+
days_in_three_years_excluding_leap_year = 365 * 3
339+
340+
with patch("coldfront.core.allocation.models.datetime") as mock_datetime:
341+
mock_datetime.date.today.return_value = self.mocked_today
342+
343+
allocation: Allocation = AllocationFactory(end_date=self.three_years_after_mocked_today)
344+
345+
self.assertEqual(allocation.expires_in, days_in_three_years_excluding_leap_year)
346+
347+
def test_end_date_in_four_years_returns_days_including_leap_day(self):
348+
"""Test that the expires_in method accounts for the extra day of a leap year."""
349+
days_in_four_years_including_leap_year = (365 * 4) + 1
350+
351+
with patch("coldfront.core.allocation.models.datetime") as mock_datetime:
352+
mock_datetime.date.today.return_value = self.mocked_today
353+
354+
allocation: Allocation = AllocationFactory(end_date=self.four_years_after_mocked_today)
355+
356+
self.assertEqual(allocation.expires_in, days_in_four_years_including_leap_year)
357+
358+
359+
360+
class AllocationModelGetInformationTests(TestCase):
361+
362+
def test_no_allocation_attributes_returns_empty_string(self):
363+
"""Test that the get_information method returns an empty string if there are no allocation attributes."""
364+
allocation: Allocation = AllocationFactory()
365+
self.assertEqual(allocation.get_information, "")
366+
367+
def test_attribute_value_is_not_a_number_returns_invalid_value_string(self):
368+
"""Test that the get_information method returns an empty string if the only attribute has value not parsable to a number."""
369+
allocation: Allocation = AllocationFactory()
370+
text_not_parsable_to_number = "this is not parsable to a number"
371+
allocation_attribute: AllocationAttribute = AllocationAttributeFactory(allocation=allocation, value=text_not_parsable_to_number)
372+
self.assertEqual(allocation.get_information, "")
373+
374+
def test_attribute_value_is_zero_returns_100_percent_string(self):
375+
allocation: Allocation = AllocationFactory()
376+
allocation_attribute: AllocationAttribute = AllocationAttributeFactory(allocation=allocation, value=0)
377+
allocation_attribute_usage = AllocationAttributeUsageFactory(allocation_attribute=allocation_attribute, value=10)
378+
379+
allocation_attribute_type_name: str = allocation_attribute.allocation_attribute_type.name
380+
allocation_attribute_usage_value: float = float(allocation_attribute_usage.value)
381+
allocation_attribute_value: str = allocation_attribute.value
382+
expected_percent = 100
383+
384+
expected_information: SafeString = format_html(
385+
"{}: {}/{} ({} %) <br>",
386+
allocation_attribute_type_name,
387+
allocation_attribute_usage_value,
388+
allocation_attribute_value,
389+
expected_percent,
390+
)
391+
392+
self.assertEqual(allocation.get_information, expected_information)
393+
394+
def test_multiple_attributes_with_same_type_returns_combined_information(self):
395+
"""Test that the get_information method returns combined information for multiple attributes."""
396+
allocation: Allocation = AllocationFactory()
397+
allocation_attribute_type = AllocationAttributeTypeFactory()
398+
399+
allocation_attribute_1: AllocationAttribute = AllocationAttributeFactory(
400+
allocation=allocation, allocation_attribute_type=allocation_attribute_type, value=100
401+
)
402+
allocation_attribute_2: AllocationAttribute = AllocationAttributeFactory(
403+
allocation=allocation, allocation_attribute_type=allocation_attribute_type, value=1000
404+
)
405+
allocation_attribute_usage_1 = AllocationAttributeUsageFactory(allocation_attribute=allocation_attribute_1, value=50)
406+
allocation_attribute_usage_2 = AllocationAttributeUsageFactory(allocation_attribute=allocation_attribute_2, value=500)
407+
408+
percent_1 = round( (float(allocation_attribute_usage_1.value) / float(allocation_attribute_1.value)) * 10_000 ) / 100
409+
percent_2 = round( (float(allocation_attribute_usage_2.value) / float(allocation_attribute_2.value)) * 10_000 ) / 100
410+
411+
expected_information: SafeString = format_html(
412+
"{}: {}/{} ({} %) <br>{}: {}/{} ({} %) <br>",
413+
allocation_attribute_type.name,
414+
float(allocation_attribute_usage_1.value),
415+
allocation_attribute_1.value,
416+
percent_1,
417+
allocation_attribute_type.name,
418+
float(allocation_attribute_usage_2.value),
419+
allocation_attribute_2.value,
420+
percent_2,
421+
)
422+
423+
self.assertEqual(allocation.get_information, expected_information)

0 commit comments

Comments
 (0)