fix sms and ticket user frindly
This commit is contained in:
1 parent
1ee83374fd
commit
b8b3aba855
30 files changed
+2220
-119
No files matched your search
+143
-10
@@ -421,6 +421,105 @@ def test_due_unread_staff_reply_is_sent_once(category,customer,monkeypatch):
|
||||
call_command("process_notifications",once=True,job_id=job.pk)
|
||||
assert len(sent)==1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_every_failed_sms_gets_exactly_three_retries_three_minutes_apart(category,customer,monkeypatch,settings):
|
||||
from django.core.management import call_command
|
||||
from apps.integrations.sms.base import SMSResult
|
||||
from apps.notifications.management.commands import process_notifications
|
||||
settings.SMS_MAX_RETRIES=3
|
||||
settings.SMS_RETRY_DELAY_SECONDS=180
|
||||
ticket=create_ticket(customer=customer,category=category,subject="آزمون retry پیامک",body="متن")
|
||||
job=NotificationJob.objects.get(ticket=ticket,event_type="CUSTOMER_TICKET_CREATED")
|
||||
calls=[]
|
||||
class Provider:
|
||||
def send_message(self,mobile,message):
|
||||
calls.append((mobile,message))
|
||||
return SMSResult(False,error="0098SMS [کد -19]: شارژ پنل برای ارسال کافی نیست.",provider_code="-19")
|
||||
monkeypatch.setattr(process_notifications,"get_sms_provider",lambda:Provider())
|
||||
|
||||
for attempt in range(1,5):
|
||||
before=timezone.now()
|
||||
call_command("process_notifications",once=True,job_id=job.pk)
|
||||
job.refresh_from_db()
|
||||
assert job.attempts==attempt
|
||||
assert job.provider_status_code=="-19"
|
||||
assert "کد -19" in job.last_error
|
||||
if attempt<4:
|
||||
assert job.status==NotificationJob.Status.RETRYING
|
||||
assert timedelta(seconds=179) <= job.next_attempt_at-before <= timedelta(seconds=181)
|
||||
NotificationJob.objects.filter(pk=job.pk).update(next_attempt_at=timezone.now()-timedelta(seconds=1))
|
||||
else:
|
||||
assert job.status==NotificationJob.Status.FAILED
|
||||
|
||||
call_command("process_notifications",once=True,job_id=job.pk)
|
||||
assert len(calls)==4
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_worker_persists_0098_delivery_result(category,customer,monkeypatch,settings):
|
||||
from django.core.management import call_command
|
||||
from apps.integrations.sms.base import SMSDeliveryResult
|
||||
from apps.notifications.management.commands import process_notifications
|
||||
ticket=create_ticket(customer=customer,category=category,subject="استعلام دلیوری",body="متن")
|
||||
job=NotificationJob.objects.get(ticket=ticket,event_type="CUSTOMER_TICKET_CREATED")
|
||||
NotificationJob.objects.filter(pk=job.pk).update(
|
||||
status=NotificationJob.Status.SENT,
|
||||
provider_message_id="123456789",
|
||||
delivery_status=NotificationJob.DeliveryStatus.PENDING,
|
||||
delivery_next_check_at=timezone.now()-timedelta(seconds=1),
|
||||
)
|
||||
class Provider:
|
||||
def get_delivery_status(self,provider_id):
|
||||
assert provider_id=="123456789"
|
||||
return SMSDeliveryResult("DELIVERED","5","0098SMS [کد 5]: پیامک به گوشی گیرنده رسیده است.")
|
||||
monkeypatch.setattr(process_notifications,"get_sms_provider",lambda:Provider())
|
||||
|
||||
call_command("process_notifications",once=True,job_id=job.pk)
|
||||
job.refresh_from_db()
|
||||
assert job.delivery_status==NotificationJob.DeliveryStatus.DELIVERED
|
||||
assert job.delivery_status_code=="5"
|
||||
assert job.delivery_next_check_at is None
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_worker_rechecks_provisional_delivery_until_definitive_result(category,customer,monkeypatch,settings):
|
||||
from django.core.management import call_command
|
||||
from apps.integrations.sms.base import SMSDeliveryResult
|
||||
from apps.notifications.management.commands import process_notifications
|
||||
settings.SMS_DELIVERY_CHECK_DELAY_SECONDS=180
|
||||
settings.SMS_DELIVERY_MAX_CHECKS=15
|
||||
ticket=create_ticket(customer=customer,category=category,subject="پیگیری طولانی دلیوری",body="متن")
|
||||
job=NotificationJob.objects.get(ticket=ticket,event_type="CUSTOMER_TICKET_CREATED")
|
||||
NotificationJob.objects.filter(pk=job.pk).update(
|
||||
status=NotificationJob.Status.SENT, sent_at=timezone.now(), provider_message_id="123456789",
|
||||
delivery_status=NotificationJob.DeliveryStatus.PENDING,
|
||||
delivery_next_check_at=timezone.now()-timedelta(seconds=1),
|
||||
)
|
||||
results=[
|
||||
SMSDeliveryResult("UNKNOWN","8","وضعیت هنوز مشخص نشده است.",is_final=False),
|
||||
SMSDeliveryResult("UNDELIVERED","6","تحویل هنوز تأیید نشده است.",is_final=False),
|
||||
SMSDeliveryResult("DELIVERED","5","پیامک به گوشی رسیده است."),
|
||||
]
|
||||
class Provider:
|
||||
def get_delivery_status(self,provider_id): return results.pop(0)
|
||||
provider=Provider()
|
||||
monkeypatch.setattr(process_notifications,"get_sms_provider",lambda:provider)
|
||||
|
||||
for expected_status,expected_attempts in ((NotificationJob.DeliveryStatus.UNKNOWN,1),(NotificationJob.DeliveryStatus.UNDELIVERED,2)):
|
||||
before=timezone.now()
|
||||
call_command("process_notifications",once=True,job_id=job.pk)
|
||||
job.refresh_from_db()
|
||||
assert job.delivery_status==expected_status
|
||||
assert job.delivery_check_attempts==expected_attempts
|
||||
assert timedelta(seconds=179) <= job.delivery_next_check_at-before <= timedelta(seconds=181)
|
||||
NotificationJob.objects.filter(pk=job.pk).update(delivery_next_check_at=timezone.now()-timedelta(seconds=1))
|
||||
|
||||
call_command("process_notifications",once=True,job_id=job.pk)
|
||||
job.refresh_from_db()
|
||||
assert job.delivery_status==NotificationJob.DeliveryStatus.DELIVERED
|
||||
assert job.delivery_check_attempts==3 and job.delivery_next_check_at is None
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_customer_ticket_created_sms_has_seven_day_magic_link(category,customer,settings,monkeypatch):
|
||||
from datetime import timedelta
|
||||
@@ -512,16 +611,50 @@ def test_behin_provider_maps_send_array_contract(settings):
|
||||
assert calls["CheckingMessageID"]=={"long":[0]}
|
||||
assert calls["SpecialNumber"]=="3000" and calls["IsFlashMessage"] is False
|
||||
|
||||
def test_0098_provider_maps_http_contract(settings,monkeypatch):
|
||||
def test_0098_provider_maps_soap_contract(settings):
|
||||
from apps.integrations.sms.sms0098 import ZeroZeroNinetyEightSMSProvider
|
||||
settings.SMS0098_USERNAME="user"; settings.SMS0098_PASSWORD="pass"; settings.SMS0098_FROM="3000"
|
||||
calls={}
|
||||
class Response:
|
||||
text="42"
|
||||
def raise_for_status(self): return None
|
||||
def fake_get(url,**kwargs): calls.update(url=url,**kwargs); return Response()
|
||||
monkeypatch.setattr("apps.integrations.sms.sms0098.requests.get",fake_get)
|
||||
result=ZeroZeroNinetyEightSMSProvider().send_message("09202202129","پیام آزمایشی")
|
||||
assert result.success and result.provider_id=="42"
|
||||
assert calls["params"]["TO"]==9202202129
|
||||
assert calls["params"]["TEXT"]=="پیام آزمایشی"
|
||||
class Service:
|
||||
def SendSMSWithID(self,**parameters): calls.update(parameters); return "123456789"
|
||||
class Client: service=Service()
|
||||
provider=ZeroZeroNinetyEightSMSProvider(); provider._client=Client()
|
||||
result=provider.send_message("09202202129","پیام آزمایشی")
|
||||
assert result.success and result.provider_id=="123456789"
|
||||
assert calls["mobileno"]=="09202202129"
|
||||
assert calls["text"]=="پیام آزمایشی"
|
||||
assert calls["pnlno"]=="3000"
|
||||
assert set(calls)=={"username","password","text","mobileno","pnlno"}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("code,expected", [
|
||||
("-3", "تطابق ندارند"), ("10", "اشتباه است"), ("11", "کاراکتر غیرمجاز"),
|
||||
("-17", "خالی است"), ("-18", "خطای شارژ"), ("-19", "شارژ پنل"),
|
||||
("-22", "شماره موبایل"), ("66", "تطابق ندارند"), ("1111", "کاراکتر غیرمجاز"),
|
||||
("Hang", "مسدود است"), ("No Doc", "مرحله دوم"), ("-23", "مجوز ارسال"),
|
||||
("-24", "شماره پنل"), ("-25", "اعتبار شماره پنل"), ("-26", "تنظیمات کد OTP"),
|
||||
("-27", "فرمت کد OTP"), ("-28", "تأیید نشده"), ("Wrong timestamp", "timestamp"),
|
||||
("Wrong time", "خارج از بازه"), ("-29", "فرمت کد OTP"), ("-31", "یافت نشد"),
|
||||
("-32", "مطابقت ندارد"), ("13", "IP غیرمجاز"),
|
||||
])
|
||||
def test_0098_provider_maps_every_documented_send_error(settings,code,expected):
|
||||
from apps.integrations.sms.sms0098 import ZeroZeroNinetyEightSMSProvider
|
||||
settings.SMS0098_USERNAME="user"; settings.SMS0098_PASSWORD="pass"; settings.SMS0098_FROM="3000"
|
||||
provider=ZeroZeroNinetyEightSMSProvider()
|
||||
result=provider._parse_send_result(code)
|
||||
assert not result.success
|
||||
assert result.provider_code==code
|
||||
assert expected in result.error
|
||||
|
||||
|
||||
@pytest.mark.parametrize("code,status,is_final", [("4","BLOCKED",True),("5","DELIVERED",True),("6","UNDELIVERED",False),("7","EXPIRED",True),("8","UNKNOWN",False),("9","ERROR",True),("12","ERROR",True),("13","ERROR",True)])
|
||||
def test_0098_provider_maps_documented_delivery_states(settings,code,status,is_final):
|
||||
from apps.integrations.sms.sms0098 import ZeroZeroNinetyEightSMSProvider
|
||||
settings.SMS0098_USERNAME="user"; settings.SMS0098_PASSWORD="pass"; settings.SMS0098_FROM="3000"
|
||||
class Service:
|
||||
def smsdeliveryState(self,**parameters): return code
|
||||
class Client: service=Service()
|
||||
provider=ZeroZeroNinetyEightSMSProvider(); provider._client=Client()
|
||||
result=provider.get_delivery_status("123456789")
|
||||
assert result.status==status and result.provider_code==code and result.is_final is is_final
|
||||
assert f"کد {code}" in result.description
|
||||
Reference in new issue
Block a user