bale group for orgs, and sms for each org
This commit is contained in:
1 parent
a18a68578f
commit
1ee83374fd
13 files changed
+262
-20
No files matched your search
@@ -88,7 +88,7 @@ def test_e2e_02_contact_group_picker_excludes_other_units(live_server, browser_p
|
||||
with browser_page() as page:
|
||||
login_staff(page, live_server, users["kimiya_ghaffari"])
|
||||
page.goto(f"{live_server.url}{reverse('staff_tickets:contact_create')}", wait_until="domcontentloaded")
|
||||
options = page.locator('select[name="groups"] option')
|
||||
options = page.locator('[data-contact-group-selector] label')
|
||||
expect(options.filter(has_text="مخاطبان فروش")).to_have_count(1)
|
||||
expect(options.filter(has_text="بارگیری انبار")).to_have_count(0)
|
||||
expect(options.filter(has_text="مالی / حسابداری")).to_have_count(0)
|
||||
@@ -96,7 +96,7 @@ def test_e2e_02_contact_group_picker_excludes_other_units(live_server, browser_p
|
||||
page.locator('input[name="first_name"]').fill("مخاطب")
|
||||
page.locator('input[name="last_name"]').fill("فروش")
|
||||
page.locator('select[name="stakeholder_type"]').select_option(CustomerProfile.StakeholderType.CUSTOMER)
|
||||
page.locator('select[name="groups"]').select_option(str(sales_group.pk))
|
||||
page.locator(f'input[name="groups"][value="{sales_group.pk}"]').check()
|
||||
with page.expect_navigation(wait_until="domcontentloaded"):
|
||||
page.get_by_role("button", name="ذخیره مخاطب").click()
|
||||
expect(page.locator("body")).to_contain_text("مخاطب فروش")
|
||||
|
||||
+130
-5
@@ -2,7 +2,7 @@ import pytest
|
||||
import base64
|
||||
from datetime import timedelta
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.exceptions import PermissionDenied, ValidationError
|
||||
from django.test import override_settings
|
||||
from django.utils import timezone
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
@@ -16,7 +16,7 @@ from apps.tickets.services import claim_ticket, create_ticket, delete_ticket, re
|
||||
|
||||
@pytest.fixture
|
||||
def category(db):
|
||||
unit = OrganizationalUnit.objects.create(name="واحد تست دامنه", slug="domain-test-unit")
|
||||
unit = OrganizationalUnit.objects.create(name="واحد تست دامنه", slug="domain-test-unit", bale_chat_id="domain-bale-group")
|
||||
unit.permissions.add(
|
||||
Permission.objects.get(codename="view_ticket", content_type__app_label="tickets"),
|
||||
Permission.objects.get(codename="add_message", content_type__app_label="messaging"),
|
||||
@@ -50,9 +50,8 @@ def test_customer_reply_enqueues_bale_group_notification(category, customer):
|
||||
assert job.next_attempt_at>=timezone.now()+timedelta(seconds=595)
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_customer_ticket_and_reply_bale_events_always_target_group(category, customer, settings, monkeypatch):
|
||||
def test_customer_ticket_and_reply_bale_events_target_owning_unit_group(category, customer, monkeypatch):
|
||||
from apps.notifications.management.commands.process_notifications import _send_bale
|
||||
settings.BALE_GROUP_CHAT_ID = "group-123"
|
||||
sent = []
|
||||
class Provider:
|
||||
def send_message(self, chat_id, text):
|
||||
@@ -68,7 +67,7 @@ def test_customer_ticket_and_reply_bale_events_always_target_group(category, cus
|
||||
reply = reply_ticket(ticket_id=ticket.pk, user=customer, body="پاسخ مشتری")
|
||||
reply_job = NotificationJob.objects.get(ticket=ticket, event_type="CUSTOMER_TICKET_REPLY")
|
||||
_send_bale(reply_job)
|
||||
assert [chat_id for chat_id, _ in sent] == ["group-123", "group-123"]
|
||||
assert [chat_id for chat_id, _ in sent] == ["domain-bale-group", "domain-bale-group"]
|
||||
assert "تیکت جدید مشتری" in sent[0][1]
|
||||
assert "پاسخ جدید مشتری" in sent[1][1]
|
||||
assert reply.body in sent[1][1]
|
||||
@@ -79,6 +78,132 @@ def test_customer_ticket_and_reply_bale_events_always_target_group(category, cus
|
||||
assert "🎫" in text and "📌 اعلان بله" in text and "📝" in text
|
||||
assert "📍 تهران" in sent[0][1]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_bale_group_notifications_are_isolated_between_units(category, customer, monkeypatch):
|
||||
from apps.notifications.management.commands.process_notifications import _send_bale
|
||||
|
||||
second_unit = OrganizationalUnit.objects.create(
|
||||
name="واحد دوم اعلان بله",
|
||||
slug="second-bale-unit",
|
||||
bale_chat_id="second-bale-group",
|
||||
)
|
||||
second_category = TicketCategory.objects.create(unit=second_unit, title="حسابداری", slug="second-bale-category")
|
||||
sent = []
|
||||
|
||||
class Provider:
|
||||
def send_message(self, chat_id, text):
|
||||
sent.append((chat_id, text))
|
||||
return type("Result", (), {"success": True})()
|
||||
|
||||
monkeypatch.setattr("apps.notifications.management.commands.process_notifications.get_bale_provider", lambda: Provider())
|
||||
first_ticket = create_ticket(customer=customer, category=category, subject="درخواست فروش", body="پیام فروش")
|
||||
second_ticket = create_ticket(customer=customer, category=second_category, subject="درخواست مالی", body="پیام مالی")
|
||||
first_reply = reply_ticket(ticket_id=first_ticket.pk, user=customer, body="پاسخ فروش")
|
||||
second_reply = reply_ticket(ticket_id=second_ticket.pk, user=customer, body="پاسخ مالی")
|
||||
|
||||
for ticket, event_type in (
|
||||
(first_ticket, "NEW_CUSTOMER_TICKET"),
|
||||
(second_ticket, "NEW_CUSTOMER_TICKET"),
|
||||
(first_ticket, "CUSTOMER_TICKET_REPLY"),
|
||||
(second_ticket, "CUSTOMER_TICKET_REPLY"),
|
||||
):
|
||||
_send_bale(NotificationJob.objects.get(ticket=ticket, event_type=event_type))
|
||||
|
||||
assert [chat_id for chat_id, _ in sent] == [
|
||||
"domain-bale-group",
|
||||
"second-bale-group",
|
||||
"domain-bale-group",
|
||||
"second-bale-group",
|
||||
]
|
||||
assert first_reply.body in sent[2][1]
|
||||
assert second_reply.body in sent[3][1]
|
||||
assert "درخواست مالی" not in sent[0][1] and "درخواست فروش" not in sent[1][1]
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_blank_unit_bale_chat_never_falls_back_to_global_group(category, customer, settings):
|
||||
settings.BALE_GROUP_CHAT_ID = "legacy-global-group"
|
||||
category.unit.bale_chat_id = ""
|
||||
category.unit.save(update_fields=["bale_chat_id", "updated_at"])
|
||||
|
||||
ticket = create_ticket(customer=customer, category=category, subject="بدون گروه", body="پیام")
|
||||
reply_ticket(ticket_id=ticket.pk, user=customer, body="پاسخ")
|
||||
|
||||
assert not NotificationJob.objects.filter(ticket=ticket, channel=NotificationJob.Channel.BALE).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_unit_notification_destinations_normalize_and_reject_duplicate_supervisors():
|
||||
unit = OrganizationalUnit(
|
||||
name="واحد مقصد اعلان",
|
||||
slug="notification-destinations",
|
||||
supervisor_mobile_1="0912 111 2233",
|
||||
supervisor_mobile_2="0935 222 3344",
|
||||
)
|
||||
unit.full_clean()
|
||||
unit.save()
|
||||
assert unit.supervisor_mobiles == ("+989121112233", "+989352223344")
|
||||
|
||||
unit.supervisor_mobile_3 = "09121112233"
|
||||
with pytest.raises(ValidationError, match="قبلاً"):
|
||||
unit.full_clean()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_new_ticket_sms_is_queued_for_each_unit_supervisor_only_on_creation(category, customer, monkeypatch):
|
||||
from apps.notifications.management.commands.process_notifications import _send_sms
|
||||
|
||||
unit = category.unit
|
||||
unit.supervisor_mobile_1 = "09121112233"
|
||||
unit.supervisor_mobile_2 = "09352223344"
|
||||
unit.supervisor_mobile_3 = "09903334455"
|
||||
unit.save()
|
||||
ticket = create_ticket(customer=customer, category=category, subject=" پیگیری بارگیری ", body="متن")
|
||||
jobs = list(NotificationJob.objects.filter(ticket=ticket, event_type="UNIT_SUPERVISOR_NEW_TICKET").order_by("id"))
|
||||
assert [job.payload["recipient_mobile"] for job in jobs] == list(unit.supervisor_mobiles)
|
||||
|
||||
sent = []
|
||||
|
||||
class Provider:
|
||||
def send_message(self, mobile, message):
|
||||
sent.append((mobile, message))
|
||||
return type("Result", (), {"success": True})()
|
||||
|
||||
monkeypatch.setattr("apps.notifications.management.commands.process_notifications.get_sms_provider", lambda: Provider())
|
||||
for job in jobs:
|
||||
result, issued_link = _send_sms(job)
|
||||
assert result.success and issued_link is None
|
||||
|
||||
assert [mobile for mobile, _ in sent] == list(unit.supervisor_mobiles)
|
||||
for _, message in sent:
|
||||
assert customer.local_mobile in message
|
||||
assert "موضوع: پیگیری بارگیری" in message
|
||||
assert f"دسته: {category.title}" in message
|
||||
|
||||
supervisor_job_count = NotificationJob.objects.filter(event_type="UNIT_SUPERVISOR_NEW_TICKET").count()
|
||||
reply_ticket(ticket_id=ticket.pk, user=customer, body="پاسخ جدید")
|
||||
assert NotificationJob.objects.filter(event_type="UNIT_SUPERVISOR_NEW_TICKET").count() == supervisor_job_count
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_staff_created_ticket_also_notifies_owning_unit_supervisors(category, customer):
|
||||
category.unit.supervisor_mobile_1 = "09124445566"
|
||||
category.unit.save()
|
||||
staff = make_staff("a")
|
||||
|
||||
ticket = create_ticket(
|
||||
customer=customer,
|
||||
created_by=staff,
|
||||
unit=category.unit,
|
||||
category=category,
|
||||
subject="ثبت توسط کارشناس",
|
||||
body="متن",
|
||||
)
|
||||
|
||||
job = NotificationJob.objects.get(ticket=ticket, event_type="UNIT_SUPERVISOR_NEW_TICKET")
|
||||
assert job.payload == {"recipient_mobile": "+989124445566"}
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_customer_bale_replies_are_debounced_by_database_policy(category,customer):
|
||||
from apps.notifications.models import NotificationPolicy
|
||||
|
||||
Reference in new issue
Block a user