voip click2calll
This commit is contained in:
1 parent
cb92abbb41
commit
38b1cf06df
18 files changed
+543
-26
No files matched your search
@@ -45,7 +45,13 @@ def test_staff_operations_pages_are_authorized_and_visually_styled(live_server,
|
||||
part = Q(content_type__app_label=app_label, codename__in=codenames)
|
||||
query = part if query is None else query | part
|
||||
unit.permissions.add(*Permission.objects.filter(query))
|
||||
staff = User.objects.create_user(username="e2e-operations", password=PASSWORD, account_type=User.AccountType.STAFF)
|
||||
staff = User.objects.create_user(
|
||||
username="e2e-operations",
|
||||
password=PASSWORD,
|
||||
account_type=User.AccountType.STAFF,
|
||||
voip_extension="300",
|
||||
voip_mobile="09384999655",
|
||||
)
|
||||
StaffProfile.objects.create(user=staff, display_name="کارشناس عملیات", primary_unit=unit)
|
||||
customer = User.objects.create_user(username="e2e-carrier", mobile="09120009121", account_type=User.AccountType.CUSTOMER)
|
||||
profile = CustomerProfile.objects.create(user=customer, first_name="باربری", stakeholder_type=CustomerProfile.StakeholderType.CARRIER)
|
||||
@@ -76,6 +82,22 @@ def test_staff_operations_pages_are_authorized_and_visually_styled(live_server,
|
||||
assert page.evaluate("getComputedStyle(document.querySelector('.operations-page')).display") == "grid"
|
||||
assert page.evaluate("document.documentElement.scrollWidth <= document.documentElement.clientWidth + 1")
|
||||
|
||||
page.goto(f"{live_server.url}{reverse('staff_tickets:contacts')}", wait_until="domcontentloaded")
|
||||
call_trigger = page.locator("[data-voip-call-trigger]").first
|
||||
call_trigger.click()
|
||||
call_menu = page.locator("body > .voip-call-menu:not([hidden])")
|
||||
expect(call_menu).to_be_visible()
|
||||
expect(call_menu.get_by_role("menuitem")).to_have_count(2)
|
||||
assert call_menu.evaluate("menu => menu.parentElement === document.body")
|
||||
assert int(call_menu.evaluate("menu => getComputedStyle(menu).zIndex")) > 100000
|
||||
menu_box = call_menu.bounding_box()
|
||||
assert menu_box is not None
|
||||
assert menu_box["x"] >= 0 and menu_box["y"] >= 0
|
||||
assert menu_box["x"] + menu_box["width"] <= page.viewport_size["width"]
|
||||
assert menu_box["y"] + menu_box["height"] <= page.viewport_size["height"]
|
||||
page.keyboard.press("Escape")
|
||||
expect(call_menu).to_be_hidden()
|
||||
|
||||
page.goto(f"{live_server.url}{reverse('staff_tickets:dispatch_create')}", wait_until="domcontentloaded")
|
||||
expect(page).to_have_title("ردیابی E2E")
|
||||
expect(page.locator(".staff-brand-copy b")).to_have_text("مرکز عملیات E2E")
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import json
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
from django.urls import reverse
|
||||
|
||||
from apps.accounts.models import User
|
||||
from apps.core.models import VoipConfiguration
|
||||
from apps.customers.models import ContactGroup, CustomerProfile
|
||||
from apps.staff.models import OrganizationalUnit, StaffProfile
|
||||
from apps.tickets.models import TicketCategory
|
||||
from apps.tickets.services import create_ticket
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def voip_data(db):
|
||||
unit = OrganizationalUnit.objects.create(name="فروش تماس", slug="voip-sales")
|
||||
group = ContactGroup.objects.create(name="مخاطبان تماس", unit=unit)
|
||||
existing_customer = User.objects.create_user(
|
||||
username="existing-voip-mobile-customer",
|
||||
mobile="09384999655",
|
||||
account_type=User.AccountType.CUSTOMER,
|
||||
)
|
||||
agent = User.objects.create_superuser(
|
||||
username="voip-agent",
|
||||
password="safe-password",
|
||||
mobile=None,
|
||||
account_type=User.AccountType.STAFF,
|
||||
voip_extension="300",
|
||||
voip_mobile="09384999655",
|
||||
)
|
||||
StaffProfile.objects.create(user=agent, primary_unit=unit, display_name="کارشناس تماس")
|
||||
customer = User.objects.create_user(
|
||||
username="voip-customer",
|
||||
mobile="09139591708",
|
||||
account_type=User.AccountType.CUSTOMER,
|
||||
)
|
||||
profile = CustomerProfile.objects.create(user=customer, first_name="مخاطب", last_name="آزمایشی")
|
||||
profile.groups.add(group)
|
||||
category = TicketCategory.objects.create(unit=unit, title="تماس فروش", slug="voip-call")
|
||||
ticket = create_ticket(customer=customer, category=category, subject="پیگیری تماس", body="شرح تماس")
|
||||
VoipConfiguration.objects.create(voip_call_url="http://127.0.0.1:9000/v1/click2call")
|
||||
assert agent.voip_mobile == existing_customer.mobile
|
||||
return agent, customer, ticket
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@pytest.mark.parametrize(
|
||||
"case",
|
||||
(
|
||||
{"method": "ip_phone", "agent_field": "agent_extension", "agent_value": "300", "key_prefix": "internal-"},
|
||||
{"method": "mobile", "agent_field": "agent_mobile", "agent_value": "09384999655", "key_prefix": "mobile-"},
|
||||
),
|
||||
)
|
||||
def test_backend_sends_voip_call(client, voip_data, case):
|
||||
agent, customer, _ = voip_data
|
||||
method = case["method"]
|
||||
client.force_login(agent)
|
||||
response_mock = Mock(content=b"{}")
|
||||
response_mock.json.return_value = {}
|
||||
with patch("apps.integrations.voip.requests.post", return_value=response_mock) as post:
|
||||
response = client.post(
|
||||
reverse("staff_tickets:contact_call", args=[customer.public_id]),
|
||||
data=json.dumps({"method": method}),
|
||||
content_type="application/json",
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
call = post.call_args
|
||||
assert call.args == ("http://127.0.0.1:9000/v1/click2call",)
|
||||
assert call.kwargs["json"] == {
|
||||
"method": method,
|
||||
case["agent_field"]: case["agent_value"],
|
||||
"customer_number": "09139591708",
|
||||
"metadata": {"agent_id": str(agent.public_id), "customer_id": str(customer.public_id)},
|
||||
}
|
||||
assert call.kwargs["headers"]["Idempotency-Key"].startswith(case["key_prefix"])
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_call_pages_hide_provider_url(client, voip_data):
|
||||
agent, customer, ticket = voip_data
|
||||
client.force_login(agent)
|
||||
for route in (
|
||||
reverse("staff_tickets:contacts"),
|
||||
reverse("staff_tickets:contact_edit", args=[customer.public_id]),
|
||||
reverse("staff_tickets:detail", args=[ticket.public_id]),
|
||||
):
|
||||
content = client.get(route).content.decode()
|
||||
assert 'data-voip-method="ip_phone"' in content
|
||||
assert 'data-voip-method="mobile"' in content
|
||||
assert reverse("staff_tickets:contact_call", args=[customer.public_id]) in content
|
||||
assert "http://127.0.0.1:9000/v1/click2call" not in content
|
||||
assert "voip-call.js" in content
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_call_method_availability(client, voip_data):
|
||||
agent, _, ticket = voip_data
|
||||
agent.voip_mobile = ""
|
||||
agent.save(update_fields=["voip_mobile"])
|
||||
client.force_login(agent)
|
||||
content = client.get(reverse("staff_tickets:detail", args=[ticket.public_id])).content.decode()
|
||||
assert 'data-voip-method="ip_phone"' in content
|
||||
assert 'data-voip-method="mobile"' not in content
|
||||
|
||||
agent.voip_call = False
|
||||
agent.save(update_fields=["voip_call"])
|
||||
content = client.get(reverse("staff_tickets:detail", args=[ticket.public_id])).content.decode()
|
||||
assert "data-voip-call" not in content
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_voip_error_is_minimal(client, voip_data):
|
||||
agent, customer, _ = voip_data
|
||||
client.force_login(agent)
|
||||
with patch("apps.integrations.voip.requests.post", side_effect=requests.ConnectionError("provider detail")):
|
||||
response = client.post(
|
||||
reverse("staff_tickets:contact_call", args=[customer.public_id]),
|
||||
data=json.dumps({"method": "mobile"}),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert response.status_code == 502
|
||||
assert response.json() == {"success": False, "message": "برقراری تماس ناموفق بود."}
|
||||
|
||||
agent.voip_call = False
|
||||
agent.save(update_fields=["voip_call"])
|
||||
response = client.post(
|
||||
reverse("staff_tickets:contact_call", args=[customer.public_id]),
|
||||
data=json.dumps({"method": "mobile"}),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert response.status_code == 403
|
||||
Reference in new issue
Block a user