@@ -0,0 +1,132 @@
|
||||
from datetime import datetime, time
|
||||
from zoneinfo import ZoneInfo
|
||||
from decimal import Decimal
|
||||
|
||||
import pytest
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.jobs.models import Application, Feedback, ScoreRun
|
||||
from apps.jobs.services.scoring import score_and_save
|
||||
from apps.notifications.models import ReminderOutbox
|
||||
from apps.notifications.services import (
|
||||
create_closing_reminders,
|
||||
create_follow_up_reminders,
|
||||
create_top_match_reminders,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_closing_reminder_is_idempotent_and_skips_hidden(profile, job):
|
||||
zone = ZoneInfo(profile.timezone)
|
||||
now = timezone.now().astimezone(zone)
|
||||
job.valid_through = datetime(
|
||||
year=now.year,
|
||||
month=now.month,
|
||||
day=now.day,
|
||||
hour=20,
|
||||
tzinfo=zone,
|
||||
)
|
||||
job.save(update_fields=["valid_through"])
|
||||
|
||||
Feedback.objects.create(
|
||||
user=profile.user,
|
||||
profile=profile,
|
||||
job=job,
|
||||
action=Feedback.Action.HIDE,
|
||||
)
|
||||
assert create_closing_reminders(profile, now=now) == []
|
||||
|
||||
Feedback.objects.filter(user=profile.user, profile=profile, job=job).delete()
|
||||
first = create_closing_reminders(profile, now=now)[0]
|
||||
second = create_closing_reminders(profile, now=now)[0]
|
||||
assert first.pk == second.pk
|
||||
assert first.status == ReminderOutbox.Status.PENDING
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_follow_up_reminder_respects_configured_weekdays(profile, job):
|
||||
zone = ZoneInfo(profile.timezone)
|
||||
now = timezone.now().astimezone(zone)
|
||||
follow_date = now.date()
|
||||
Application.objects.create(
|
||||
user=profile.user,
|
||||
job=job,
|
||||
follow_up_date=follow_date,
|
||||
status=Application.Status.APPLIED,
|
||||
notes="",
|
||||
)
|
||||
profile.follow_up_weekdays = [(follow_date.weekday() + 1) % 7]
|
||||
profile.save(update_fields=["follow_up_weekdays"])
|
||||
assert create_follow_up_reminders(profile, now=now) == []
|
||||
|
||||
profile.follow_up_weekdays = [follow_date.weekday()]
|
||||
profile.save(update_fields=["follow_up_weekdays"])
|
||||
reminders = create_follow_up_reminders(profile, now=now)
|
||||
assert len(reminders) == 1
|
||||
assert reminders[0].reminder_type == ReminderOutbox.ReminderType.FOLLOW_UP
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_top_match_reminder_requires_threshold_and_profile_setting(profile, job):
|
||||
profile.top_match_reminders_enabled = True
|
||||
profile.top_match_threshold = 90
|
||||
profile.save(update_fields=["top_match_reminders_enabled", "top_match_threshold"])
|
||||
score = score_and_save(job, profile)
|
||||
score.recommendation = ScoreRun.Recommendation.STRONG
|
||||
score.score = 85
|
||||
score.confidence = Decimal("0.9")
|
||||
score.save(update_fields=["recommendation", "score", "confidence"])
|
||||
|
||||
assert create_top_match_reminders(profile) == []
|
||||
|
||||
score.score = 95
|
||||
score.confidence = Decimal("0.90")
|
||||
score.save(update_fields=["score", "confidence"])
|
||||
score.confidence = Decimal("0.84")
|
||||
score.save(update_fields=["confidence"])
|
||||
assert create_top_match_reminders(profile) == []
|
||||
|
||||
score.confidence = Decimal("0.86")
|
||||
score.save(update_fields=["confidence"])
|
||||
reminders = create_top_match_reminders(profile)
|
||||
assert len(reminders) == 1
|
||||
assert reminders[0].reminder_type == ReminderOutbox.ReminderType.TOP_MATCH
|
||||
|
||||
profile.top_match_reminders_enabled = False
|
||||
profile.save(update_fields=["top_match_reminders_enabled"])
|
||||
assert create_top_match_reminders(profile) == []
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_reminder_obeys_quiet_hours_and_empty_recipient(profile, job):
|
||||
zone = ZoneInfo(profile.timezone)
|
||||
now = timezone.now().astimezone(zone).replace(hour=6, minute=30, second=0, microsecond=0)
|
||||
job.valid_through = datetime(
|
||||
year=now.year,
|
||||
month=now.month,
|
||||
day=now.day,
|
||||
hour=18,
|
||||
tzinfo=zone,
|
||||
)
|
||||
job.save(update_fields=["valid_through"])
|
||||
|
||||
profile.user.email = ""
|
||||
profile.user.save(update_fields=["email"])
|
||||
assert create_closing_reminders(profile, now=now)[0].status == ReminderOutbox.Status.SKIPPED
|
||||
|
||||
profile.user.email = "reminder@example.invalid"
|
||||
profile.user.save(update_fields=["email"])
|
||||
reminder = create_closing_reminders(profile, now=now)[0]
|
||||
assert reminder.status == ReminderOutbox.Status.PENDING
|
||||
assert reminder.scheduled_for.timetz().replace(tzinfo=None) == time(7, 0)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_reminder_service_handles_dst_dates(profile, job):
|
||||
zone = ZoneInfo(profile.timezone)
|
||||
now = datetime(2026, 10, 25, 1, 30, tzinfo=zone)
|
||||
job.valid_through = now.replace(hour=20)
|
||||
job.save(update_fields=["valid_through"])
|
||||
reminder = create_closing_reminders(profile, now=now)[0]
|
||||
assert reminder.scheduled_for.tzinfo is not None
|
||||
assert reminder.scheduled_for.tzinfo.key == "Europe/Brussels"
|
||||
Reference in New Issue
Block a user