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
@@ -1,7 +1,11 @@
|
||||
import base64
|
||||
from datetime import timedelta
|
||||
|
||||
import pytest
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from apps.accounts.models import MagicLinkAccessLog, TicketMagicLink, User
|
||||
from apps.attachments.models import AttachmentPolicy
|
||||
@@ -157,6 +161,41 @@ def test_group_dispatch_copies_shared_document_into_each_private_ticket():
|
||||
assert len(set(paths))==2
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dispatch_page_supports_professional_multi_attachment_picker_and_submission(client):
|
||||
unit=OrganizationalUnit.objects.create(name="واحد پیوست گروهی",slug="dispatch-attachment-unit")
|
||||
unit.permissions.add(Permission.objects.get(codename="dispatch_group_tickets",content_type__app_label="tickets"))
|
||||
staff=make_staff("dispatch-attachment-staff",unit)
|
||||
customer=make_contact("dispatch-attachment-customer","09120000313")
|
||||
group=ContactGroup.objects.create(name="گروه پیوست",unit=unit)
|
||||
customer.customer_profile.groups.add(group)
|
||||
category=TicketCategory.objects.create(unit=unit,title="اسناد گروهی",slug="dispatch-attachments-category")
|
||||
AttachmentPolicy.objects.update_or_create(attachment_type="IMAGE",defaults={"max_file_size":1024*1024,"max_files_per_message":10,"allowed_extensions":[".png"],"allowed_mime_types":["image/png"]})
|
||||
AttachmentPolicy.objects.update_or_create(attachment_type="PDF",defaults={"max_file_size":1024*1024,"max_files_per_message":10,"allowed_extensions":[".pdf"],"allowed_mime_types":["application/pdf"]})
|
||||
client.force_login(staff)
|
||||
url=reverse("staff_tickets:dispatch_create")
|
||||
|
||||
page=client.get(url)
|
||||
content=page.content.decode()
|
||||
assert page.status_code==200
|
||||
for marker in ("data-ticket-composer","data-gallery-input","data-document-input","data-file-preview","attachment-uploader.js"):
|
||||
assert marker in content
|
||||
assert "افزودن عکس از گالری" in content and "افزودن فایل" in content
|
||||
|
||||
response=client.post(url,{
|
||||
"operation_type":GroupDispatch.OperationType.BULK,"unit":unit.pk,"contact_group":group.pk,
|
||||
"category":category.pk,"subject":"ارسال چند پیوست گروهی","body":"تصویر و سند را بررسی کنید.",
|
||||
"files":[
|
||||
SimpleUploadedFile("preview.png",base64.b64decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII="),content_type="image/png"),
|
||||
SimpleUploadedFile("document.pdf",b"%PDF-1.4\n%%EOF",content_type="application/pdf"),
|
||||
],
|
||||
})
|
||||
|
||||
assert response.status_code==302, response.context["form"].errors.as_json() if response.context else response.content.decode()
|
||||
ticket=Ticket.objects.get(subject="ارسال چند پیوست گروهی")
|
||||
assert set(ticket.ticket_messages.get().attachments.values_list("original_name",flat=True))=={"preview.png","document.pdf"}
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_magic_link_records_every_open_with_ip_and_user_agent(client):
|
||||
unit = OrganizationalUnit.objects.create(name="حسابداری ممیزی", slug="audit-accounting")
|
||||
@@ -367,29 +406,87 @@ def test_unit_scoped_add_ticket_preserves_contact_ownership_and_stakeholder(clie
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dispatch_retry_is_unit_scoped_and_refreshes_persistent_status(client):
|
||||
from apps.core.templatetags.jalali import jalali_datetime
|
||||
|
||||
unit=OrganizationalUnit.objects.create(name="لوجستیک retry",slug="logistics-retry")
|
||||
other=OrganizationalUnit.objects.create(name="فروش retry",slug="sales-retry")
|
||||
permission=Permission.objects.get(content_type__app_label="tickets",codename="dispatch_group_tickets")
|
||||
unit.permissions.add(permission)
|
||||
unit.permissions.add(permission,Permission.objects.get(content_type__app_label="tickets",codename="view_ticket"))
|
||||
staff=make_staff("retry-dispatcher",unit); outsider=make_staff("retry-outsider",other)
|
||||
contact=make_contact("retry-carrier","09120000302")
|
||||
group=ContactGroup.objects.create(name="باربری retry",unit=unit); contact.customer_profile.groups.add(group)
|
||||
category=TicketCategory.objects.create(title="استعلام retry",slug="quote-retry")
|
||||
dispatch,tickets=dispatch_group_tickets(user=staff,unit=unit,contact_group=group,category=category,subject="استعلام هزینه جدید",body="قیمت را ثبت کنید.")
|
||||
job=NotificationJob.objects.get(ticket=tickets[0],channel="SMS")
|
||||
job.status=NotificationJob.Status.FAILED; job.attempts=3; job.last_error="provider"; job.save()
|
||||
job.status=NotificationJob.Status.FAILED; job.attempts=4; job.last_error="0098SMS [کد -19]: شارژ پنل برای ارسال کافی نیست."; job.provider_status_code="-19"; job.save()
|
||||
for _ in range(4):
|
||||
TicketMagicLink.issue_with_record(tickets[0],reason="staff_created_ticket",created_by=staff)
|
||||
# Supervisor alerts are separate from the recipient message and must not
|
||||
# alter dispatch metrics or become the row's displayed/retryable SMS.
|
||||
NotificationJob.objects.create(
|
||||
channel=NotificationJob.Channel.SMS,event_type="UNIT_SUPERVISOR_NEW_TICKET",
|
||||
ticket=tickets[0],customer=tickets[0].customer,payload={"recipient_mobile":"09120000999"},
|
||||
status=NotificationJob.Status.SENT,attempts=1,next_attempt_at=timezone.now(),
|
||||
dedupe_key=f"test-supervisor-{tickets[0].pk}",
|
||||
)
|
||||
refresh_group_dispatch_status(dispatch.pk); dispatch.refresh_from_db()
|
||||
assert dispatch.status==GroupDispatch.Status.PARTIAL
|
||||
|
||||
client.force_login(staff)
|
||||
detail=client.get(reverse("staff_tickets:dispatch_detail",args=[dispatch.public_id]))
|
||||
content=detail.content.decode()
|
||||
assert detail.status_code==200
|
||||
assert "قیمت را ثبت کنید." in content
|
||||
assert "متن اولیه کارشناس" in content
|
||||
assert "کد -19" in content and "شارژ پنل" in content
|
||||
assert "جزئیات فنی و رهگیری" in content
|
||||
assert jalali_datetime(dispatch.created_at) in content
|
||||
assert dispatch.created_at.strftime("%Y/%m/%d %H:%M") not in content
|
||||
assert "0 + 0" not in content
|
||||
assert "مشاهده نشده" in content
|
||||
assert detail.context["tickets"][0].sms_job.pk==job.pk
|
||||
assert detail.context["metrics"]["failed"]==1
|
||||
ticket_detail=client.get(reverse("staff_tickets:detail",args=[tickets[0].public_id]))
|
||||
assert ticket_detail.status_code==200
|
||||
assert "علت دقیق" in ticket_detail.content.decode() and "کد -19" in ticket_detail.content.decode()
|
||||
|
||||
client.force_login(outsider)
|
||||
assert client.post(reverse("staff_tickets:dispatch_retry",args=[dispatch.public_id])).status_code==403
|
||||
client.force_login(staff)
|
||||
assert client.post(reverse("staff_tickets:dispatch_retry",args=[dispatch.public_id])).status_code==302
|
||||
assert client.post(reverse("staff_tickets:dispatch_retry",args=[dispatch.public_id]),{"job_id":job.pk}).status_code==302
|
||||
job.refresh_from_db(); dispatch.refresh_from_db()
|
||||
assert (job.status,job.attempts,job.last_error)==(NotificationJob.Status.PENDING,0,"")
|
||||
assert job.provider_status_code=="" and job.delivery_status==""
|
||||
assert dispatch.status==GroupDispatch.Status.QUEUED
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_provisional_delivery_is_tracking_not_failure_or_manual_retry(client):
|
||||
unit=OrganizationalUnit.objects.create(name="پیگیری دلیوری",slug="delivery-tracking-unit")
|
||||
unit.permissions.add(*Permission.objects.filter(content_type__app_label="tickets",codename__in=("view_ticket","dispatch_group_tickets")))
|
||||
staff=make_staff("delivery-tracking-agent",unit)
|
||||
contact=make_contact("delivery-tracking-contact","09120000322")
|
||||
group=ContactGroup.objects.create(name="گروه پیگیری",unit=unit); contact.customer_profile.groups.add(group)
|
||||
category=TicketCategory.objects.create(unit=unit,title="پیگیری",slug="delivery-tracking-category")
|
||||
dispatch,tickets=dispatch_group_tickets(user=staff,unit=unit,contact_group=group,category=category,subject="پیگیری تحویل",body="متن")
|
||||
job=NotificationJob.objects.get(ticket=tickets[0],event_type="STAFF_TICKET_CREATED")
|
||||
NotificationJob.objects.filter(pk=job.pk).update(
|
||||
status=NotificationJob.Status.SENT,attempts=1,sent_at=timezone.now(),provider_message_id="123456789",
|
||||
delivery_status=NotificationJob.DeliveryStatus.UNKNOWN,delivery_status_code="8",
|
||||
delivery_next_check_at=timezone.now()+timedelta(minutes=3),delivery_check_attempts=1,
|
||||
)
|
||||
refresh_group_dispatch_status(dispatch.pk); dispatch.refresh_from_db()
|
||||
assert dispatch.status==GroupDispatch.Status.SENT
|
||||
|
||||
client.force_login(staff)
|
||||
detail=client.get(reverse("staff_tickets:dispatch_detail",args=[dispatch.public_id]))
|
||||
assert detail.context["metrics"]["tracking"]==1 and detail.context["metrics"]["failed"]==0
|
||||
assert detail.context["tickets"][0].sms_retryable is False
|
||||
client.post(reverse("staff_tickets:dispatch_retry",args=[dispatch.public_id]),{"job_id":job.pk})
|
||||
job.refresh_from_db()
|
||||
assert job.status==NotificationJob.Status.SENT and job.delivery_status==NotificationJob.DeliveryStatus.UNKNOWN
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_magic_link_can_be_revoked_only_with_unit_permission(client):
|
||||
unit=OrganizationalUnit.objects.create(name="حسابرسی",slug="audit-unit")
|
||||
|
||||
Reference in new issue
Block a user